Replace By Fee 기능

Replace By Fee (RFB) 기능

Replace By Fee

만약 Bitcoin 트랜잭션이 낮은 Transaction Fee를 가지고 있어서 MemPool 에 Stuck 되어 있다면, 사용자는 오랜 시간 동안 트랜잭션이 처리되기를 기다리게 된다. 이런 경우 Transaction Fee를 올려 트랜잭션을 수정할 수 있는데, 이를 Replace By Fee (RFB) 기능이라 한다. Replace By Fee는 BIP-125 에 의해 도입된(v0.12에서 처음 도입) 기능으로 v0.14 에서 완전히 구현되었다.

Replace By Fee 기능을 사용하기 위해서는 Transaction Input에 있는 Sequence 필드를 1 ~ (0xffffffff-2) 사이의 값으로 설정하여야 한다. Sequence 필드는 비트코인 초기에 어떤 목적을 위해 사용하려 하였으나, 실제로는 사용되지 않았다. 이후 개발자들이 Time lock 이나 Replace By Fee 기능을 위해 이 필드를 활용하였다. Replace By Fee 기능을 사용하기 위해 그리고 Time lock과의 충돌을 피하기 위해, 일반적으로 Sequence 필드에 1 을 지정하거나 0xf0000000 ~ (0xffffffff-2) 범위의 값을 사용한다.

참고로, bitcoind가 실행될 때 -walletrfb 파라미터를 지정하거나 bitcoin.conf에 walletrbf=1 을 지정하면 Replace By Fee 기능이 디폴트로 On 된다. 즉, 이 RBF 플래그가 사용되면 Sequence 가 자동으로 Replace By Fee 기능을 사용하도록 설정된다.

#bitcoin.conf
walletrbf=1 

Replace By Fee 기능이 사용되면 Unconfirmed Transaction 에서 bip125-replaceable = yes 로 설정된다. 물론 Transaction이 confirm 되면, 더 이상 Replace 되지 않기 때문에 gettransaction 에서 bip125-replaceable = no 로 표시된다.

Replace By Fee 사용

(1) bumpfee 명령 사용

Bitcoin Core 0.14 부터 bumpfee 명령을 사용하여 Fee를 상향 조정할 수 있다. 얼마만큼 Fee를 올리는 지는 bitcoind 가 구성파일에 지정된 값들을 참조하여 결정한다.

$ bitcoin-cli -named bumpfee txid=db495a167e173267c54e722a920a88c41dcfcd6b5aab0635c3fd5cefee6ce5c4
(2) Raw Transaction 활용

Low level에서 보다 정교하게 Replace By Fee 기능을 사용하기 위해서는 Raw Transaction을 사용한다.

예를 들어, 0.00111 BTC에서 0.00110800 을 보내면, Fee는 200 Sats가 된다. createrawtransaction으로 트랜잭션을 생성할 때, Replace By Fee 기능을 사용하기 위해 (구성파일 설정이 없는 경우) "sequence": 1 을 지정한다.

    $ bitcoin-cli -named createrawtransaction inputs='[{"txid": "21449bb9f74511003ffcd0de1f8300b86903fc65338370fd64adcb4ffd9c371e", "vout": 0, "sequence": 1 }]' outputs='[{"tb1qr78u2cm7dspt3m065kknfarm562m2lamfjfnz2":0.00110800}]'
    $ bitcoin-cli signrawtransactionwithwallet 02000000011e379cfd4fcbad64fd708333...
    $ bitcoin-cli sendrawtransaction 42100000000000100000001d4e...

생성된 트랜잭션을 보면 bip125-replaceable이 yes로 설정된 것을 볼 수 있다.

$ bitcoin-cli gettransaction db495a167e173267c54e7...
{
  "amount": 0.00000000,
  "fee": -0.00000200,
  "confirmations": 0,
  "trusted": true,
  "walletconflicts": [
  ],
  "time": 1646162420,
  "timereceived": 1646162420,
  "bip125-replaceable": "yes",   ***
   ...
   ... 
}

위와 같이 낮은 Fee를 갖는 트랜잭션이 Stuck 되어 있다면, 좀 더 높은 Fee를 갖는 새 트랜잭션을 만들어 다시 보낼 수 있다. 아래 예제에서는 임의로 0.0011 BTC 을 보내면서 Fee를 1000 sats 로 만들고 있다.

    $ bitcoin-cli -named createrawtransaction inputs='[{"txid": "21449bb9f74511003ffcd0de1f8300b86903fc65338370fd64adcb4ffd9c371e", "vout": 0, "sequence": 1 }]' outputs='[{"tb1qr78u2cm7dspt3m065kknfarm562m2lamfjfnz2":0.0011}]'
    $ bitcoin-cli signrawtransactionwithwallet ...
    $ bitcoin-cli sendrawtransaction ...

새로 생성된 트랜잭션을 보면, Fee가 1000 sats 로 되고, walletconflicts 에 낮은 Fee를 갖는 원래 트랜잭션이 표시된다. Fee를 여러번 올리면, 이전 트랜잭션들이 여기에 표시된다.

$ bitcoin-cli gettransaction 4617282399aeeaebe...
{
    "amount": 0.00000000,
    "fee": -0.00001000,   *** Fee
    "confirmations": 0,
    "trusted": true,
    "walletconflicts": [
        "db495a167e173267c54e7..."   *** conflict txid
    ],
    "time": 1646162620,
    "timereceived": 1646162620,
    "bip125-replaceable": "yes",
    ... 
    ... 

RFB가 사용되면 Miner는 높은 Fee의 트랜잭션을 블럭에 포함하여 Confirm 하게 된다. 이때 낮은 Fee의 트랜잭션은 Confirmation 필드가 음수값을 갖게 되는데, 이는 높은 Fee 트랜잭션이 Confirm 된 시점으로부터 역계산되어 음수값으로 표신된 것이다. 이 낮은 Fee 트랜잭션을 시간이 지남에 따라 결국 MemPool에서 삭제된다.

$ bitcoin-cli gettransaction db495a167e173267c...
{
    "amount": 0.00000000,
    "fee": -0.00000162,
    "confirmations": -2,   *** 음수값
    "trusted": false,
    ... 
    ... 
본 웹사이트는 광고를 포함하고 있습니다. 광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.