rippleのAccount Familyとは
- 一つのシード鍵から複数のリップルアドレスを生成するもの(BIP32のようなもの)
- rippleでは利用は推奨されていないのか公式でトランザクションを署名する方法が用意されていないので注意する
- リップルのアドレス生成の根幹をなすのでsから始まるキーからアドレスを生成する仕組みを知る上では必須の概念
- https://wiki.ripple.com/Account_Family
- https://steemit.com/ripple/@ripplerm/ripple-understanding-passphrase-secret-key-and-address-account
このドキュメントでは ripple-account-family というライブラリを使って解説します
カギ生成の流れ
- イメージ
seed -> privateGenerator(rootKey) -> publicGenerator
* publicGenerator -> publicKey -> address
* privateGenerator -> privateKey -> publicKey -> address
seedというのはsから始まるシード鍵です
秘密鍵はプライベートジェネレータからつくられます
公開鍵はパブリックジェネレータまたは秘密鍵からつくられます
リップルのアドレスは2パターンの生成方法があることがわかります
実装例
コード
const addressCodec = require("ripple-address-codec")
const af = require("ripple-account-family").af
const seed = "ss7vwFuNi2Zud1ekn68LivP2P7UF1"
const entropy = addressCodec.decodeSeed(seed)
// seed -> privateGenerator
const privateGenerator = af.createPrivateGenerator(entropy.bytes)
console.log("privateGenerator:" + privateGenerator.toString('hex').toUpperCase())
// privateGenerator -> publicGenerator
const publicGenerator = af.createPublicGenerator(privateGenerator)
console.log("publicGenerator:" + publicGenerator.toString('hex').toUpperCase())
// privateGenerator -> privateKey -> publicKey
const privatekey = af.derivePrivateKey(privateGenerator, 0)
console.log("privateKey:" + '00' + privatekey.toString('hex').toUpperCase())
const publickey1 = af.privateKeyToPublicKey(privatekey)
console.log("publicKey(from privateKey):" + publickey1.toString('hex').toUpperCase())
// publicGenerator -> publicKey
const publickey2 = af.derivePublicKey(publicGenerator, 0)
console.log("publicKey(from publicGenerator):" + publickey2.toString('hex').toUpperCase())
結果
privateGenerator:852662BA3F5D8BE463B079BF49814281D9D32DE502DE745BFC47F43E1C50517B
publicGenerator:03D3469DD45441E9180AB679ECB34CE0D8DB14B18851E3510207C5DB534E8DBB84
privateKey:00539B10B560ED769501ADF011E1CC286C4EE88F0B8786EA9C4F6254BEDEBDB788
publicKey(from privateKey):0246FC105E7DC5585CC9848BA7BC1B6BE1C8E9F27E5FD5C5600C4EF0EAF36A866A
publicKey(from publicGenerator):0246FC105E7DC5585CC9848BA7BC1B6BE1C8E9F27E5FD5C5600C4EF0EAF36A866A
プライベートジェネレータ と パブリックジェネレータ2つの方法で公開鍵を作成していますが、同じ結果になっているのがわかります
パブリックジェネレータからは秘密鍵を作成できないのでパブリックジェネレータだけをサーバーなどに載せることで安全にリップルアドレスを大量に作成することができます。
ただし大量に生成できるといってもリップルはアカウントをアクティベートするのに20XRPの準備金が必要なのと
destination_tagという誰からの入金か識別する機能があるので一つのマスターキーからリップルアドレスを大量に生成できても使いみちがあまりないのが現状です
マルチアカウント
複数のアカウントを一つの鍵から用意したい場合に検討できる
0番はトレード用(ゲートハブなど)、1番は資金保管用など用途別に分けたいときなど。
コード
const RootWallet = require("ripple-account-family").RootWallet
const seed = "ss7vwFuNi2Zud1ekn68LivP2P7UF1"
// シード鍵からウォレットを生成します
const rw = new RootWallet(seed)
// アカウントを5つ生成します
const list = Array(5).fill(0).map((v,i)=> rw.derive(i).getInfo())
// 結果
console.log(JSON.stringify(list, null, 2))
結果
[
{
"index": 0,
"address": "rGNqu4V2so6RV7Wa8GcFjoaBhG1kmuhzv9",
"publickey": "0246FC105E7DC5585CC9848BA7BC1B6BE1C8E9F27E5FD5C5600C4EF0EAF36A866A",
"privatekey": "00539B10B560ED769501ADF011E1CC286C4EE88F0B8786EA9C4F6254BEDEBDB788"
},
{
"index": 1,
"address": "rpizJneWQRwf4CwyeTnpi2oa4smkvuBXV2",
"publickey": "02DD414E520C1FECB8EF5FA43AAD0710136B3ECF8FF94EA18FE77BCBED424EA3DD",
"privatekey": "007961A9E76503755BC9B56EBE05D139821D95484D5646E30FDE7467876A518719"
},
{
"index": 2,
"address": "rnqK81gKj5E9xswsFTc1oY7LGqqT2PV3hi",
"publickey": "02A6BED4FB05BB480ADD021C085D3B6122A559C5126E37662AEA302570D8121E93",
"privatekey": "005E53CBE79F039592D1E4FD8EA6D231118780BA8DA9A395190E2F05F0D95AFC31"
},
{
"index": 3,
"address": "rPA5eByNMyyJqWj15cN6e1QNqb9fq6WQLz",
"publickey": "02FB4C0B67FBB1FD97FC69E6B109EFFE3EE89DEEEDD504B7C6F408872EE99035AE",
"privatekey": "00EA82AB887E09DDBDAB36316A7AADAC893AAA3248C895238EF66033F34F112973"
},
{
"index": 4,
"address": "rPhZ9qgw8GHe4hUXULorUnEfGLddjQRFK2",
"publickey": "03277E1C92B553832DC398134C6CA5014B7EB2FC49627FF85707DE6F56534BCB83",
"privatekey": "00F3C6BB1C08737AB5DA527B71AEB0ACCA9976CE7D90E73333FE420C8B40E125D4"
}
]
このコードからは一つのシード鍵から複数のリップルアカウントが作られているのがわかります
コールドウォレット版マルチアカウント
送金が必要ない場合はコールドウォレットを検討できる
コード
const ColdWallet = require("ripple-account-family").ColdWallet
// パブリックジェネレータからコールドウォレットを生成します
const cw = new ColdWallet("03D3469DD45441E9180AB679ECB34CE0D8DB14B18851E3510207C5DB534E8DBB84")
// アカウントを5つ生成します
const f = (n) => ({index:n, address:cw.getAddress(n)})
const list = Array(5).fill(0).map((v, i)=> f(i))
// 結果
console.log(JSON.stringify(list, null, 2))
結果
[
{
"index": 0,
"address": "rGNqu4V2so6RV7Wa8GcFjoaBhG1kmuhzv9"
},
{
"index": 1,
"address": "rpizJneWQRwf4CwyeTnpi2oa4smkvuBXV2"
},
{
"index": 2,
"address": "rnqK81gKj5E9xswsFTc1oY7LGqqT2PV3hi"
},
{
"index": 3,
"address": "rPA5eByNMyyJqWj15cN6e1QNqb9fq6WQLz"
},
{
"index": 4,
"address": "rPhZ9qgw8GHe4hUXULorUnEfGLddjQRFK2"
}
]
秘密鍵なしにリップルアドレスを生成できる事がわかる