수수료를 대납할 수 있는 계정을 받으셨나요? 그런데 받은 private key에서 생성되는 주소와 지급 받은 계정의 주소가 일치하지 않나요?
먼저 이 질문에 대한 답변을 하기 이전에 AccountKey이 무엇인지 알아야 합니다.
AccountKey
Klaytn에서는 계정의 키를 업데이트할 수 있다는 것을 아시나요? Klaytn의 계정은 주소와 키가 분리되며, 이 때에 Klaytn 네트워크에 저장되는 계정의 키(public key value)가 바로 AccountKey입니다.
기존의 블록체인 네트워크에서는 private key → public key → address 가 강결합 상태로 묶여 있어서, 만약 private key가 노출된다면 새로운 계정을 만들어야 했습니다. 하지만 Klaytn에서는 당신의 계정의 주소를 그대로 유지한 채로 새롭게 사용할 private key만 변경할 수 있는 기능을 제공합니다.
이에 대해서 더욱 자세한 내용은 Klaytn Docs를 참고해 주세요 !
AccountKey 확인하기
그럼 지급받은 수수료 대납용 계정의 AccountKey가 무엇인지 실제로 확인해 보도록 하죠.
caver를 사용할 수도 있지만, 여기서는 terminal에서 바로 RPC API를 사용하여 노드에게 요청을 보내 결과를 확인해 봅시다.
curl -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"klay_getAccountKey","params":["0x5a51664639409096E1A4C36439d53c4b0c9F996A", "latest"],"id":1}' https://api.baobab.klaytn.net:8651
위의 명령어에서 파라미터에 전달되는 주소를 대납용으로 지급받은 계정의 주소로, 마지막에 오는 노드의 주소는 당신이 API를 호출하고자 하는 노드의 주소로 변경하여 실행해 보세요. 위 예제에 나와 있는 계정의 주소는 제가 Baobab 네트워크에서 AccountKeyRoleBased로 업데이트한 계정의 주소입니다.
위의 명령어를 실행하여 아래와 같이 계정의 키를 확인할 수 있습니다.
{
jsonrpc: ‘2.0’,
id: 1,
result: {
keyType: 5,
key: [
{ keyType: 2, key: { x: ‘0x56e00…’, y: ‘0x705c3…’ } },
{ keyType: 2, key: { x: ‘0xea42f…’, y: ‘0x3b7a8…’ } },
{ keyType: 2, key: { x: ‘0x88ee9…’, y: ‘0x134c3…’ } },
],
},
}
위의 결과의 "keyType: 5"가 바로 AccountKeyRoleBased에 해당하는 ID입니다. 자세한 내용은 Klaytn Docs를 참고하세요.
AccountKeyRoleBased
수수료 대납용 계정은 계정의 역할에 대한 권한을 분리하기 위하여 AccountKeyRoleBased로 업데이트 된 계정입니다. 여러분이 받으신 키는 AccountKeyRoleBased의 RoleFeePayer 역할에 사용되는 키입니다. 해당 키로는 수수료를 대납하는 행위만 수행할 수 있는 것이죠.
이렇게 수수료 대납용 계정은 키와 주소를 결합을 끊고 역할 별로 사용하는 키가 다른 AccountKeyRoleBased로 업데이트된 계정입니다. 그렇기 때문에 지급 받은 키에서 생성되는 주소는 수수료 대납용 계정의 주소와 다릅니다.
Decoupled Account 사용 방법
수수료 대납용 계정을 사용하여 트랜잭션에 서명하는 방법에 대해서 궁금한가요? 수수료를 대납하는 계정의 주소를 발급받은 주소로 지정하고, 트랜잭션에 서명(fee payer)할 때에 지급 받은 RoleFeePayer키로 서명하면 됩니다.
아래의 코드는 대표적인 예로 caver-js를 사용하여 수수료 대납자가 트랜잭션에 서명하는 방법에 대해 설명합니다.
async function feePayer() {
// 지급받은 키와 주소
const feePayerKey = '0x{private key}'
const address = '0x{address in hex}'
// caver-js의 in-memory wallet에 계정 add
// 만약 in-memory wallet을 사용하지 않는다면 feePayerSignTransaction 호출 시에 3 번째 파라미터로 서명에 사용될 키를 넘겨주면 됩
const feePayerAccount = caver.klay.accounts.createWithAccountKey(address, { feePayerKey })
caver.klay.accounts.wallet.add(feePayerAccount)
// 트랜잭션 오브젝트 혹은 sender가 서명한 rawTransaction string을 파라미터로 전달하여 서명요청 가능(senderRawTransaction)
const feeDelegatedValueTransferTx = {
type: 'FEE_DELEGATED_VALUE_TRANSFER',
...
}
const feePayerSigned = await caver.klay.accounts.feePayerSignTransaction(feeDelegatedValueTransferTx, feePayerAccount.address)
}
좀 더 자세한 사용법에 대해서는 Klaytn Docs를 참고해 주세요.
caver-java를 사용하여 수수료 대납자가 서명하는 방법에 대해서는 caver-java의 Getting Started를 참고해 주세요.
만약 EN 노드에 API콜을 직접 호출하고 싶다면, 통신하는 EN노드가 personal API를 허용해야 합니다. 만약 EN노드가 personal API를 허용한다면 다음 절차를 따라 수행하세요.
- personal API를 사용하여 import raw key를 하여 노드에 수수료 대납용 계정 추가
- 계정 사용을 위해 unlock을 수행
- 수수료 대납자 서명을 요청하는 klay_sendTransationAsFeePayer API를 호출
결론
계정이 수수료 대납을 할 수 있는 키를 분리하기 위하여 계정의 키를 AccountKeyRoleBased로 업데이트 하였기 때문에 계정의 키와 주소는 분리되게 된 것이고, 대납용으로 지급 받은 키에서 파생된 주소와 실제 대납 계정의 주소는 다른것 입니다.
대납용으로 지급받은 계정의 주소가 왜 다른지 이해가 되셨나요? 아직 이해가 되지 않았거나, 질문이 있다면 언제든지 말씀하세요! 어떠한 피드백도 환영합니다.