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

**URL:** <https://devforum.kaia.io/t/topic/104>\
**Category:** Caver\
**Created:** [3월 2, 2020, 7:16오전 UTC](https://devforum.kaia.io/t/topic/104 "2020-03-02T07:16:05Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jamie](https://yyz1.discourse-cdn.com/flex035/user_avatar/devforum.kaia.io/jamie/32/1472_2.png) [@Jamie](https://devforum.kaia.io/u/Jamie)\
**Post date:** [3월 2, 2020, 7:16오전 UTC](https://devforum.kaia.io/t/topic/104/1 "2020-03-02T07:16:05Z")

</div>

대납을 사용하여 컨트랙트를 실행하기 위해서는 ‘FEE\_DELEGATED\_SMART\_CONTRACT\_EXECUTION’ 타입이나 ‘FEE\_DELEGATED\_SMART\_CONTRACT\_EXECUTION\_WITH\_RATIO’ 타입의 트랜잭션을 전송하면 됩니다.

두 트랜잭션의 차이점에 대해서는 [대납을 사용하여 컨트랙트 배포를 어떻게 하나요?](https://devforum.kaia.io/t/topic/102)에 설명된 글을 참고해 주세요.

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

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

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

아래부터는 개발 환경과 테스트에 사용할 계정이 모두 갖추어져 있다는 것을 전제로 설명됩니다. 만약 처음 시작한다면 [Klaytn Docs](https://ko.docs.klaytn.com/bapp/sdk/caver-js/getting-started#starting-with-caver-js)를 참고하여 개발 환경을 세팅하고 [충분한 테스트넷 KLAY를 소유하고 있는 계정](https://ko.docs.klaytn.com/bapp/sdk/caver-js/getting-started#getting-klay-via-baobab-faucet)을 준비해 주세요.

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

**테스트 계정 추가하기**

테스트넷 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](https://ko.docs.klaytn.com/bapp/sdk/caver-js/api-references/caver.klay.abi#encodefunctioncall)을 통하여 인코딩된 값을 구할 수 있습니다.

그리고 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\_\*’ 타입의 트랜잭션을 생성하고, 트랜잭션을 발생시킨 서비스 사용자와 수수료를 대납하는 서비스 제공자 모두 트랜잭션에 서명한 뒤, 네트워크로 전송하면 됩니다.

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