튜토리얼에 앞서
API 호출에 사용되는 x-chain-id
값은 8217(Cypress) 또는 1001(Baobab)입니다.
API 호출에 필요한 필수 파라미터는 각 예시에 설명됩니다.
API 호출 시 사용자가 입력해야 하는 값은 중괄호 1개({}
)로 표시합니다. 사용자가 입력해야 하는 값은 아래 테이블과 같습니다.
Cypress(Klaytn 메인넷) 또는 Baobab(Klaytn 테스트넷)
KAS 콘솔 - Security - Credential에서 발급받은 accessKeyId
KAS 콘솔 - Security - Credential에서 발급받은 secretAccessKey
API 인증 키가 있으면 모든 KAS 서비스를 사용할 수 있으며 Wallet API를 호출해 만든 Klaytn 계정에 대한 모든 권한을 소유합니다. 모든 권한에는 Klaytn 계정의 자산(KLAY 등) 이동이나 전송 및 실행 권한이 포함됩니다. 만약 API 인증 키에 타인이 접근한다면 Klaytn 계정 권한을 탈취당해 원치 않는 트랜잭션이 발생할 수 있습니다.
KAS/Klaytn 계정 보안을 위해 KAS API 인증 키(Secret Access Key)를 타인과 함부로 공유하지 말고 주의해 관리하십시오.
다중 서명이란?
다중 서명이란 말 그대로 여러개의 서명을 의미합니다. 클레이튼은 트랜잭션을 보내기 전에 트랜잭션에 서명을 받아야 합니다. 이 때, 1개 트랜잭션에 여러 클레이튼 계정이 서명해야 하는 경우가 있습니다. 이는 트랜잭션을 보내려는 계정이 다중 서명 계정, 즉 를 가진 계정인 경우입니다.
다중 서명을 받는 트랜잭션 보내기
Klay를 보내려면 Klaytn Node에 트랜잭션을 보내야 하며, 트랜잭션을 보내려면 트랜잭션 수수료를 지불해야 합니다. API를 호출하려면 계정 저장소와 계정을 생성하고 사용할 계정을 선택해야 합니다. 이 예시를 따라 트랜잭션을 보내면, 보내는는 계정(Account)이 트랜잭션 수수료를 직접 부담합니다.
다중 서명을 받는 트랜잭션 전송 예시로써, KLAY 전송 트랜잭션을 보낼 때 여러 계정으로 서명하는 단계는 아래와 같습니다.
보류 중인 트랜잭션 목록 조회
현재 계정에서 보낸 트랜잭션 중 보류중인 트랜잭션 목록을 조회합니다.
현재 계정이 다중 서명 계정이고 트랜잭션을 전송하는 데 서명을 충분히 받지 못한 경우(=이미 서명에 사용된 키들의 가중치 합이 기준치를 넘지 못한 경우) 트랜잭션 상태(status
)는 보류(Pending
) 상태입니다. 다중 서명 계정으로 트랜잭션을 전송했어도 트랜잭션을 전송하기 위한 서명 개수가 부족하다면 트랜잭션은 필요한 서명을 모두 받을 때까지 보류 상태입니다.
API를 호출하려면 계정 저장소와 계정을 생성하고 사용할 계정을 선택해야 합니다.
API 호출
입력한 클레이튼 계정 주소(EOA)에서 보낸 트랜잭션 중에서 보류 중인 트랜잭션들을 불러오는 API를 호출합니다. API 호출 시 REST API 또는 SDKs(caver-js, caver-java extensions)를 사용할 수 있습니다.
쿼리 파라미터
응답 아이템 개수 (min=1, max=1000, default=100)
페이지네이션으로 다음 요청을 보낼 때 필요한 커서
검색 범위: 마지막 시간의 타임스탬프 (초단위)
검색 범위: 시작 시간의 타임스탬프 (초단위)
Copy curl --location --request GET "https://wallet-api.klaytnapi.com/v2/multisig/account/0xc6C9356887b7F7887918Bf577417E5D8De253295/tx" \
-u {access-key-id}:{secret-access-key} \
--header "x-chain-id: {chain-id}" \
Copy const result = await caver.kas.wallet.getMultiSigTransactionList('0x3EE8aC5eBDDcF408020D1125437302B2267e5A8C')
Copy MultisigTransactions transactions = caver.kas.wallet.getMultiSigTransactionList("0xBF19457580DcF1ed9E586F0C74747311a0d9d070");
System.out.println(transactions);
API 응답
보류 중인 트랜잭션 목록 조회 API의 응답은 아래와 같습니다.
Copy {
"cursor": "",
"items": [
{
"address": "0xc6C9356887b7F7887918Bf577417E5D8De253295",
"chainId": 1001,
"createdAt": 1599144020,
"multiSigKeys": [
{
"address": "0xc6C9356887b7F7887918Bf577417E5D8De253295",
"weight": 3
},
{
"address": "0x0b7caaf70e7A0a5399041c64711E535CE8B3cf7d",
"weight": 1
}
],
"status": 2,
"threshold": 4,
"transactionId": "0x65111d4fba621a1bfa3bd97c219b3e0454471cf3c07827396f1202946df51ee2",
"txData": {
"from": "0xc6c9356887b7f7887918bf577417e5d8de253295",
"gasLimit": 1000000,
"gasPrice": "0x5d21dba00",
"input": "0x6d656d6f",
"to": "0x2f87ba64de5526f7880f21481effbf950f70005c",
"typeInt": 16,
"value": "0x1001"
},
"type": "TX",
"updatedAt": 1599144020
},
{
"address": "0xc6C9356887b7F7887918Bf577417E5D8De253295",
"chainId": 1001,
"createdAt": 1599144013,
"multiSigKeys": [
{
"address": "0xc6C9356887b7F7887918Bf577417E5D8De253295",
"weight": 3
},
{
"address": "0x0b7caaf70e7A0a5399041c64711E535CE8B3cf7d",
"weight": 1
}
],
"status": 2,
"threshold": 4,
"transactionId": "0x36f9c5794fc141d3625e89a1164e6105fa973e8214d23bc6a210d2afe9dba6dd",
"txData": {
"from": "0xc6c9356887b7f7887918bf577417e5d8de253295",
"gasLimit": 1000000,
"gasPrice": "0x5d21dba00",
"input": "0x6d656d6f",
"to": "0x2f87ba64de5526f7880f21481effbf950f70005c",
"typeInt": 16,
"value": "0x100"
},
"type": "TX",
"updatedAt": 1599144013
}
]
}
Copy MultisigTransactions {
cursor: '',
items: [
PendedTransaction {
chainId: 1001,
createdAt: 1602119611,
status: 2,
threshold: 3,
transactionId: '0xff94d85dd096b8f7d46763e226e0998346e9d75ba813cfd73520f700bf0207a0',
updatedAt: 1602119611,
address: '0x3EE8aC5eBDDcF408020D1125437302B2267e5A8C',
multiSigKeys: [
MultisigAddress {
address: '0x38614901Dcd4FAF796A0e2FE8aC19E5147A59f3f',
weight: 1
},
MultisigAddress {
address: '0x9E5FE19695ac38239E4432eC5BE7bBEFcc4d415A',
weight: 1
},
MultisigAddress {
address: '0xB7B4f049eFC6B650ACCDa59229a46B19210c2cfA',
weight: 1
}
],
txData: TxData {
from: '0x3ee8ac5ebddcf408020d1125437302b2267e5a8c',
gas: 25000,
gasPrice: '0x5d21dba00',
to: '0x76c6b1f34562ed7a843786e1d7f57d0d7948a6f1',
typeInt: 8,
value: '0x1'
},
type: 'TX'
}
]
}
Copy class MultisigTransactions {
cursor:
items: [class PendedTransaction {
address: 0xBF19457580DcF1ed9E586F0C74747311a0d9d070
chainId: 1001
createdAt: 1602562698
multiSigKeys: [class MultisigAddress {
address: 0xBF19457580DcF1ed9E586F0C74747311a0d9d070
weight: 2
}, class MultisigAddress {
address: 0x9dF8f1c6d7E6A1206083DB8e1e51d7dAe28B0312
weight: 2
}, class MultisigAddress {
address: 0xB011BE8EB2898417D53A91E6979118D157638C5d
weight: 2
}]
status: 2
threshold: 3
transactionId: 0x86e3ab3978a73264af4fa968240b278f81196189803d038ef2da3e92f364c5aa
txData: class TxData {
from: 0xbf19457580dcf1ed9e586f0c74747311a0d9d070
gas: 100000
gasPrice: 0x5d21dba00
input: null
to: 0x95e3fd82ecd2b32cae8618599971f5f47f4bc110
typeInt: 8
value: 0x1
}
type: TX
updatedAt: 1602562698
}]
}
보류 중인 트랜잭션에 서명하기
API를 호출하려면 계정 저장소와 계정을 생성하고 사용할 계정을 선택해야 합니다.
API 호출
보류 중인 트랜잭션 서명 API를 호출합니다. API 호출 시 REST API 또는 SDKs(caver-js, caver-java extensions)를 사용할 수 있습니다.
Copy curl --location --request POST "https://wallet-api.klaytnapi.com/v2/multisig/account/0x68Da92c0557A62C292598A3156B770df6e07BD83/tx/0x5d7beaf43d63d27bf8ddd11ac32ee3c853abfe869988526f92431a63fe3dcb1d/sign" \
-u {access-key-id}:{secret-access-key} \
--header "x-chain-id: {chain-id}" \
Copy const address = '0x127089fF8154B145e8dcad7C112A949C2a452cb8'
const transactionId = '0xfe2be4de37ed40c6c049d3c2771a6e7577916c951dd331b297b517b25609b4ad'
const result = await caver.kas.wallet.signMultiSigTransction(address, transactionId)
Copy String address = "0x9dF8f1c6d7E6A1206083DB8e1e51d7dAe28B0312";
String transactionId = "0x86e3ab3978a73264af4fa968240b278f81196189803d038ef2da3e92f364c5aa";
MultisigTransactionStatus status = caver.kas.wallet.signMultiSigTransaction(address, transactionId);
System.out.println(status);
API 응답
보류 중인 트랜잭션 서명 API의 응답은 아래와 같습니다.
Copy // 전체 가중치 합계가 4(=기준치) 이상이어야 하는 상황에서, 일부 서명만 받았을 경우: 가중치 1짜리 서명만 받은 경우
{
"reminders": [
"0xf24e881d3cFF241859203DB09a28421267B7F6E6"
],
"signedWeight": 1,
"status": "Signed",
"threshold": 4,
"transactionID": "0xfa275dba88d197a85504ef70e0dd2640acc708817e9eb3933d7850acfb048649",
"weight": 1
}
// 전체 가중치 합계가 4(=기준치) 이상이어야 하는 상황에서, 트랜잭션 전송에 필요한 모든 서명을 받았을 경우: : 가중치 1짜리 서명과 가중치 3짜리 서명까지 받은 경우
{
"signedWeight": 4,
"status": "Submitted",
"threshold": 4,
"transactionHash": "0x81f2ff422eae9b40d65b7a6f1e3c5ca598f83d1473ccc87e53d51b875fe75c82",
"transactionID": "0xfa275dba88d197a85504ef70e0dd2640acc708817e9eb3933d7850acfb048649",
"weight": 3
}
Copy MultisigTransactionStatus {
signedWeight: 1,
status: 'Signed',
threshold: 3,
transactionId: '0xfe2be4de37ed40c6c049d3c2771a6e7577916c951dd331b297b517b25609b4ad',
weight: 1,
reminders: [
'0xc4Dd4D041430c65d95CaaF6fB1506A542d6583d0',
'0x55afF286674559caB1Fd4427C91C4cC045766140'
]
}
Copy class MultisigTransactionStatus {
signedWeight: 4
status: Submitted
threshold: 3
transactionHash: 0xa9286090d32df1aa8aa08235293bc0ddaffc84dc74b712d827a7a93e7eff9e36
transactionId: 0x86e3ab3978a73264af4fa968240b278f81196189803d038ef2da3e92f364c5aa
weight: 2
reminders: [0xB011BE8EB2898417D53A91E6979118D157638C5d]
}
reminders
: 아직 서명하지 않은 키의 주인인 계정 주소
signedWeight
: 이 트랜잭션에 여태까지 서명된 키들의 가중치 누적합으로 이 값이 threshold
보다 커야 트랜잭션이 전송됨
보류 중인 트랜잭션에 서명하기 - 미리 준비한 서명 사용하기
보류중인 트랜잭션에 서명합니다. 이 때 미리 준비한 서명 값으로 보류중인 트랜잭션에 서명합니다.
KAS 외부에서 만든 Klaytn 계정이 있고 이 계정의 서명 값이 있다면, 이 서명 값으로 트랜잭션에 서명할 수 있습니다. 현재 계정이 다중 서명 계정이고 트랜잭션을 전송하는 데 서명을 충분히 받지 못한 경우(=이미 서명에 사용된 키들의 가중치 합이 기준치를 넘지 못한 경우) 트랜잭션 상태(status
)는 보류(Pending
) 상태입니다.
API를 호출하려면 계정 저장소와 계정을 생성하고 사용할 계정을 선택해야 합니다.
API 호출
보류 중인 트랜잭션 서명 API를 호출합니다. API 호출 시 REST API 또는 SDKs(caver-js, caver-java extensions)를 사용할 수 있습니다.
Copy curl --location --request POST "https://wallet-api.klaytnapi.com/v2/multisig/tx/0x5d7beaf43d63d27bf8ddd11ac32ee3c853abfe869988526f92431a63fe3dcb1d/sign" \
-u {access-key-id}:{secret-access-key} \
--header "x-chain-id: {chain-id}" \
--header "Content-Type: application/json" \
--data-raw "{
"signatures": [
{
"R": "0xaa2ae446f5dd35df839e8ec2005aede91f0b3ea0f1e6889f4294d4760529bfaf",
"S": "0x7b3efab682bcc86f7050819e12a2b5ea916871d684b9e1c8ca8f49869df41896",
"V": "0x7f5"
}
]
}"
Copy const transactionId = '0x7e7f18b16fb1807654d9cd2b1ad1c0cbb649b81648543a792a6db2f43e1a8ad5'
const signatures = [
{
V: '0x7f6'
R: '0xc2902ebb52f554fd257eda57a3fe7cbf1e046bb43d1472bd396f2c3053f8bf55',
S: '0x32f7d5b99e91510ecaefc5fe65816e6e43043c408873b2453d02116be1674278',
}
]
const result = await caver.kas.wallet.appendSignatures(transactionId, signatures)
Copy String transactionID = "0x7e7f18b16fb1807654d9cd2b1ad1c0cbb649b81648543a792a6db2f43e1a8ad5";
Signature signature = new Signature();
signature.setV("0x7f6");
signature.setR("0xeacce28162b45142d2eefb77f124e15384597745cbf5996d3bfa5d61186e1769");
signature.setS("0x5254543d277f7b471dd684d349cde586f34e04ed935ed57fd4c66171883e947b");
SignPendingTransactionBySigRequest request = new SignPendingTransactionBySigRequest();
request.setSignatures(Arrays.asList(signature));
MultisigTransactionStatus transactionStatus = caver.kas.wallet.appendSignatures(transactionID, request);
System.out.println(transactionStatus);
signatures
: ECDSA 서명 정보(R,S)와 공개키 복원 정보(V)로 구성된 미리 준비한 서명값입니다.
API 응답
보류 중인 트랜잭션 서명 API의 응답은 아래와 같습니다.
Copy // 다중 서명이 필요한 상황에서, 일부 서명만 받았을 경우: 기준치 4에 가중치 3짜리 서명만 받은 경우
{
"reminders": [
"0xA9183eD590ebEDf06D415ae684E3f18d06789f8d"
],
"signedWeight": 3,
"status": "Signed",
"threshold": 4,
"transactionId": "0xa0cabe28c75aa6babbf7e85b5033641c46d0f2e7b714e47103716695d454a45a",
"weight": 3
}
// 다중 서명이 필요한 상황에서, 트랜잭션 전송에 필요한 모든 서명을 받았을 경우: : 기준치 4에 가중치 1짜리 서명까지 받은 경우
{
"signedWeight": 4,
"status": "Submitted",
"threshold": 4,
"transactionHash": "0xf1ced3855f3cd1d5220f2991ec4ba845ec747a0c01028c2d63de3662ddad2083",
"transactionId": "0xae20ed8ce084d372fb804ea6f6073ba2f485a64bac086199efb83d665d0b31f2",
"weight": 1
}
Copy MultisigTransactionStatus {
signedWeight: 1,
status: 'Signed',
threshold: 3,
transactionId: '0x7e7f18b16fb1807654d9cd2b1ad1c0cbb649b81648543a792a6db2f43e1a8ad5',
weight: 1,
reminders: [
'0x54f91a712DAd60F78Fbb49E6043DF35dA37842Fd',
'0x7725Ef7B7372Fd6E9093E8fA57f2c8a4c0622b8c'
]
}
Copy class MultisigTransactionStatus {
signedWeight: 4
status: Submitted
threshold: 3
transactionHash: 0x9d969960396e66c4abe2e2495b852f1b99835f310c3f66d2f7b34eea43e29122
transactionId: 0x7e7f18b16fb1807654d9cd2b1ad1c0cbb649b81648543a792a6db2f43e1a8ad5
weight: 2
reminders: [0x9dF8f1c6d7E6A1206083DB8e1e51d7dAe28B0312]
}
reminders
: 아직 서명하지 않은 키의 주인인 계정 주소
signedWeight
: 이 트랜잭션에 여태까지 서명된 키들의 가중치 누적합으로 이 값이 threshold
보다 커야 트랜잭션이 전송됨