-
-
Save anonymous/b935887caec15849cb15 to your computer and use it in GitHub Desktop.
RBFのフラグが立っているかどうかをみるためのjavascript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 普通のjavaScriptで、今度Bitcoin Coreに実装されるRBFの希望するためのフラグを読んで | |
// 生取引からそのフラグが立っているかどうかを返す isRBF の関数が入っています。 | |
/** | |
* 生取引データの文字列を入れ、RBFのフラグが立っているかどうかを返す | |
* @param {string} rawtx 生取引データの文字列。例:"0100000001ae4d..." | |
* @return {bool} RBFのフラグが立っているかどうか | |
*/ | |
function isRBF(rawtx) { | |
// nSequenceの値を配列で返す | |
var sequences = getSequenceValues(rawtx); | |
// nSequenceが全て 0xffffffff ならRBFじゃないので false を返す | |
for (var i = 0; i < sequences.length; i++) { | |
// 一個でも 0xffffffff じゃない nSequenceがあれば、RBFなので true | |
if (sequences[i] !== 0xffffffff) return true; | |
}; | |
return false; | |
}; | |
/** | |
* 生取引データの文字列を入れ、入力のnSequenceを全て返す | |
* @param {string} rawtx 生取引データの文字列。例:"0100000001ae4d..." | |
* @return {number[]} 各入力のnSequence値を配列に入れたもの | |
*/ | |
function getSequenceValues(rawtx) { | |
//戻り値 | |
var ret = []; | |
// バージョン番号トル | |
rawtx = rawtx.slice(8); | |
var input_count = readVarInt(rawtx); | |
var sigScriptLen; | |
// 入力数のVarIntトル | |
rawtx = rawtx.slice(input_count.length * 2); | |
for (var i = 0; i < input_count.value; i++) { | |
// 入力のtxOutHashとtxOutIndexトル | |
rawtx = rawtx.slice(64 + 8); | |
sigScriptLen = readVarInt(rawtx); | |
// 入力のvarIntとscriptSigトル | |
rawtx = rawtx.slice((sigScriptLen.length * 2) + (sigScriptLen.value * 2)); | |
// 入力のnSequenceを配列に挿入 | |
ret.push(parseInt(rawtx.slice(0, 8), 16)); | |
// 入力のnSequenceトルと次の入力が先頭にくる | |
rawtx = rawtx.slice(8); | |
}; | |
return ret; | |
}; | |
/** | |
* varIntの値が先頭にある生取引の一部を入れて、varInt自体のバイト数と | |
* varIntの値をオブジェクトとして返す | |
* @param {string} hex varIntが先頭にある文字列。例:"fd02018c62..." | |
* @return {object} パラメータはlength : バイト数, value : 値 | |
*/ | |
function readVarInt(hex) { | |
// 1バイト以下はダメ | |
if (hex.length < 2) throw "VarInt must be at least 1 byte!"; | |
// 頭のバイトが長さを教えてくれる。 | |
var first = parseInt(hex.slice(0,2), 16); | |
var intval; | |
var intlen; | |
if (first < 0xfd) { | |
// 0xfd以下のものは1バイトの長さです。そのままが値になる。 | |
intval = first; | |
intlen = 1; | |
} else if (first === 0xfd) { | |
if (hex.length < 6) throw "VarInt starting with 0xfd must be at least 3 bytes!"; | |
// 0xfdのものは3バイトの長さです。残り2バイトはリトルエンディアンなので、バイトの順番を逆にする。 | |
intval = parseInt(hex.slice(4,6) + hex.slice(2,4), 16); | |
intlen = 3; | |
} else if (first === 0xfe) { | |
if (hex.length < 10) throw "VarInt starting with 0xfe must be at least 5 bytes!"; | |
// 0xfeのものは5バイトの長さです。残り4バイトはリトルエンディアンなので、バイトの順番を逆にする。 | |
intval = parseInt(hex.slice(8,10) + hex.slice(6,8) + hex.slice(4,6) + hex.slice(2,4), 16); | |
intlen = 5; | |
} else if (first === 0xff) { | |
if (hex.length < 18) throw "VarInt starting with 0xff must be at least 9 bytes!"; | |
// 0xffのものは9バイトの長さです。残り8バイトはリトルエンディアンなので、バイトの順番を逆にする。 | |
intval = parseInt(hex.slice(16,18) + hex.slice(14,16) + hex.slice(12,14) + hex.slice(10,12) + hex.slice(8,10) + hex.slice(6,8) + hex.slice(4,6) + hex.slice(2,4), 16); | |
// javaScriptのparseIntに上限がある。この数字を超えるvarIntはビットコイン取引の中であり得ないのだが、念のため。 | |
if (intval > 9007199254740991) throw "javascript parseInt does not support hex values over 0x1fffffffffffff"; | |
intlen = 9; | |
}; | |
return {length: intlen, value: intval}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
if (sequences[i] !== 0xffffffff) return true;
is incorrect. The sequence number must be less than 0xfffffffd since 0xfffffffe does not signal RBF but does signal locktime.