대납을 사용하여 컨트랙트 실행을 어떻게 하나요?

대납을 사용하여 컨트랙트를 실행하기 위해서는 ‘FEE_DELEGATED_SMART_CONTRACT_EXECUTION’ 타입이나 ‘FEE_DELEGATED_SMART_CONTRACT_EXECUTION_WITH_RATIO’ 타입의 트랜잭션을 전송하면 됩니다.

두 트랜잭션의 차이점에 대해서는 대납을 사용하여 컨트랙트 배포를 어떻게 하나요?에 설명된 글을 참고해 주세요.

그럼 바로 대납을 사용하여 트랜잭션을 실행하는 방법에 대해서 알아보도록 합시다!

수수료 대납하여 트랜잭션 실행하기

실제로 caver-js를 통해 대납으로 스마트 컨트랙트를 실행하는 방법에 대해서 알아볼까요?

아래부터는 개발 환경과 테스트에 사용할 계정이 모두 갖추어져 있다는 것을 전제로 설명됩니다. 만약 처음 시작한다면 Klaytn Docs를 참고하여 개발 환경을 세팅하고 충분한 테스트넷 KLAY를 소유하고 있는 계정을 준비해 주세요.

여기서는 추가적으로 실행할 스마트 컨트랙트의 주소도 필요합니다!

테스트 계정 추가하기

테스트넷 KLAY를 충분히 가지고 있는 계정이 준비되었다면, 이를 caver-js의 in-memory wallet에 아래와 같이 추가합니다.

const caver = new Caver('http://13.125.198.123:8551/')

const address = '0x474d331644171af43e50b5414a4b47c8abfc6f32'
const key = '55288a6f1b2390d7c592d22b7aa7c0a9f14f895aa4cf39b3da62b5502a2f6b16'
// create Account instance
const account = caver.klay.accounts.createWithAccountKey(address, key)
// Add to in-memory wallet
caver.klay.accounts.wallet.add(account)

const feePayerAddress = '0xbe3590e4060259b9b45c8a9248c2c928a3694a26'
const feePayerKey = 'f5a23d229e11753cea04500fa916e14ebf1a8166cfeca69988e54f682578e674'
const feePayerAccount = caver.klay.accounts.createWithAccountKey(feePayerAddress, feePayerKey)
caver.klay.accounts.wallet.add(feePayerAccount)

in-memory wallet에 계정을 추가한 이후, caver.klay.accounts에 트랜잭션 서명 요청을 보내면 내부에 저장된 계정의 키로 서명하여 리턴합니다.

대납 트랜잭션 생성하기

여기서는 대납으로 스마트 컨트랙트를 실행하기 위하여 ‘FEE_DELEGATED_SMART_CONTRACT_EXECUTION_WITH_RATIO’ 타입의 트랜잭션을 사용합니다.

const contractAddrss = '0x156f9403ec30613923259E9559875C5d1143D2bA'

const txObject = {
    type: 'FEE_DELEGATED_SMART_CONTRACT_EXECUTION_WITH_RATIO',
    from: account.address,
    to: contractAddrss,
    data: '0x{encoded function call}',
    value: 0,
    gas: 50000,
    feeRatio: 80,
}

이 예제의 data에는 호출하고자 하는 함수의 function signature와 파라미터가 함께 인코딩된 값을 입력해 주세요. encoded function call을 통하여 인코딩된 값을 구할 수 있습니다.

그리고 feeRatio에 지정된 80의 의미는 수수료 대납자가 80%의 수수료를 대납하며, 서비스 사용자(트랜잭션을 발생시킨 사용자)가 20%의 수수료를 지불한다는 의미입니다.

서명하기

위에서 생성한 트랜잭션을 서명해 볼까요?

그럼 먼저 서비스 사용자의 서명을 해봅시다.

const senderSigned = await caver.klay.accounts.signTransaction(txObject)

위의 코드는 in-memory wallet 내부에서 from 주소에 해당하는 계정의 키로 트랜잭션에 서명한 뒤 결과를 리턴합니다. 해당 리턴 오브젝트 내부에는 ‘rawTransaction’ 필드에 RLP-encoded signed transaction이 함께 리턴됩니다. 수수료 대납자는 rawTransaction을 통하여 서명을 할 수 있습니다. 그럼 수수료 대납자도 이제 서명을 해볼까요?

const feePayerSigned = await caver.klay.accounts.feePayerSignTransaction(senderSigned.rawTransaction, feePayerAccount.address)

위에 예제에 보면 senderSigned.rawTransaction을 파라미터로 첫 번째 파라미터로 전송합니다. 이 값에는 트랜잭션의 정보와 서비스 사용자(트랜잭션을 발생시킨 사용자)의 서명이 모두 포함되어 있습니다. 그리고 두 번째 파라미터로는 수수료 대납자의 주소를 전달합니다. feePayerSignTransation은 전달 받은 트랜잭션에 수수료 대납자로써 서명한 후 결과값을 리턴합니다. 이전과 동일하게 ‘rawTransaction’ 필드에는 RLP-encoded signed transaction이 함께 리턴됩니다. 이 값에는 서비스 사용자와 서비스 제공자의 서명이 모두 포함되어 있습니다.

트랜잭션 전송하기

트랜잭션에 서명까지 완료했다면, 이제 네트워크에 전송하여 실제로 스마트 컨트랙트를 실행하는 작업만 남아있습니다.

const receipt = await caver.klay.sendSignedTransaction(feePayerSigned.rawTransaction)
console.log(receipt)

RLP-encoded signed transaction을 파라미터로 caver.klay.sendSignedTransaction을 호출하면 네트워크로 트랜잭션을 전송하여 실제로 스마트 컨트랙트를 실행할 수 있습니다.

결론

caver-js를 통하여 대납을 하는 방법을 간단합니다. ‘FEE_DELEGATED_*’ 타입의 트랜잭션을 생성하고, 트랜잭션을 발생시킨 서비스 사용자와 수수료를 대납하는 서비스 제공자 모두 트랜잭션에 서명한 뒤, 네트워크로 전송하면 됩니다.

이해가 안되는 부분이나 추가적인 궁금증이 있는 경우에는 편하게 댓글을 남겨주세요 ! :hugs:

2개의 좋아요