IPrivacy.singleProofBatchTransfer
singleProofBatchTransfer(
PrivacySingleProofBatchTransferRequest request
) external returns (bool success) 다중 입력·다중 출력의 배치 join-split을 단일 Groth16 증명으로 검증하여 적용합니다. 입력 개수는 1..BatchJoinSplitV1MaxInputs, 출력 개수는 1..BatchJoinSplitV1MaxOutputs 범위여야 합니다. 범위를 벗어나면 PrivacyBatchSizeOutOfRange(count, max)로 revert됩니다. 실패는 IPrivacy의 타입 지정 커스텀 오류 또는 IPrecompile의 상속 오류로 노출됩니다.
파라미터
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
request | PrivacySingleProofBatchTransferRequest | ✓ | 단일 증명 배치 페이로드입니다. 하나의 proof, 하나의 root, 입력 nullifier 배열, 출력 항목 배열(각 항목은 커밋먼트 + 암호문 + 공개 필드), audit 키 메타데이터, audit 공개 대상 pubkey, expiresAtUnix를 포함합니다. |
반환값
타입:
bool 성공 시 true를 반환합니다. 실패는 false 반환이 아니라 타입 지정 커스텀 오류로 revert됩니다.
에러
| 코드 | 이름 | 설명 |
|---|---|---|
PrivacyBatchSizeOutOfRange | PrivacyBatchSizeOutOfRange | 입력 개수가 1..BatchJoinSplitV1MaxInputs 범위를 벗어나거나 출력 개수가 1..BatchJoinSplitV1MaxOutputs 범위를 벗어날 때 revert됩니다. 페이로드는 (count, max)입니다. |
PrivacyRequestExpired | PrivacyRequestExpired | request.expiresAtUnix가 0이거나 이미 지났을 때 revert됩니다. |
PrivacyDuplicateNullifier | PrivacyDuplicateNullifier | 같은 nullifier가 request.nullifiers에 두 번 이상 나타날 때 revert됩니다. |
PrivacyNullifierAlreadySpent | PrivacyNullifierAlreadySpent | 어떤 nullifier가 이미 온체인에 기록되어 있을 때 revert됩니다. |
PrivacyDuplicateCommitment | PrivacyDuplicateCommitment | 같은 출력 커밋먼트가 request.outputs에 두 번 이상 나타날 때 revert됩니다. |
PrivacyCommitmentAlreadyExists | PrivacyCommitmentAlreadyExists | 어떤 출력 커밋먼트가 이미 Merkle 트리에 존재할 때 revert됩니다. |
PrivacyMerkleCapacityExceeded | PrivacyMerkleCapacityExceeded | 출력을 추가하면 셸디드 풀 Merkle 트리 용량을 초과할 때 revert됩니다. |
PrivacyTxLimitExceeded | PrivacyTxLimitExceeded | 트랜잭션이 이미 전역 stateful-privacy 호출 한도를 초과했을 때 revert됩니다. |
InvalidNumberOfArgs | InvalidNumberOfArgs | IPrecompile에서 상속됩니다. 호출이 정확히 하나의 인자를 담고 있지 않을 때 revert됩니다. |
예제
두 노트를 하나로 병합
단일 증명이 join-split 전체를 승인합니다. 모든 입력이 같은 발신자의 것이라면 다중 증명 batchTransfer보다 비용이 저렴합니다.
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { privacyAbi } from "@maroo-chain/contracts/abi/IPrivacy";
const PRIVACY = "0x100000000000000000000000000000000000000b" as const;
const wallet = createWalletClient({
account: privateKeyToAccount(process.env.SENDER_KEY as `0x${string}`),
transport: http("https://rpc-testnet.maroo.io"),
});
// request.nullifiers.length in 1..BatchJoinSplitV1MaxInputs;
// request.outputs.length in 1..BatchJoinSplitV1MaxOutputs.
await wallet.writeContract({
address: PRIVACY,
abi: privacyAbi,
functionName: "singleProofBatchTransfer",
args: [request],
}); 크기 위반 처리
PrivacyBatchSizeOutOfRange는 입력과 출력 모두에 대해 발생합니다. 인터페이스의 BatchJoinSplitV1MaxInputs / BatchJoinSplitV1MaxOutputs 한도와 대조해 문제가 된 값을 로깅합니다.
import { decodeErrorResult } from "viem";
import { privacyAbi } from "@maroo-chain/contracts/abi/IPrivacy";
try {
await wallet.writeContract({
address: PRIVACY,
abi: privacyAbi,
functionName: "singleProofBatchTransfer",
args: [request],
});
} catch (err: any) {
if (!err?.data) throw err;
const decoded = decodeErrorResult({ abi: privacyAbi, data: err.data });
if (decoded.errorName === "PrivacyBatchSizeOutOfRange") {
const [count, max] = decoded.args as [bigint, bigint];
console.warn(`batch input or output count ${count} exceeds max ${max}`);
} else {
throw err;
}
}