Skip to content

Instantly share code, notes, and snippets.

@motopig
Last active May 18, 2020 06:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save motopig/e2f03569700af765869025c84750c981 to your computer and use it in GitHub Desktop.
Save motopig/e2f03569700af765869025c84750c981 to your computer and use it in GitHub Desktop.
比特币多签交易签名
// 多签转账第一次签名
const publickeys = this.pubKeys.map(this.filter);
const p2ms = bitcoin.payments.p2ms({
m: this.multWallet.passNum,
pubkeys: publickeys,
network: bitcoin.networks.bitcoin,
});
const p2sh = bitcoin.payments.p2sh({ redeem: p2ms });
// 创建新的transaction
txb = new bitcoin.TransactionBuilder(bitcoin.networks.bitcoin);
txb.setVersion(1);
// 多签钱包未花费是否为空
if (res.unspent_outputs.length) {
// transaction 中增加未花费input
res.unspent_outputs.forEach((item) => {
txb.addInput(item.tx_hash_big_endian, item.tx_output_n);
});
if (this.remark) {
const data = Buffer.from(this.remark, 'utf8');
const embed = bitcoin.payments.embed({ data: [data] });
// transaction 中增加备注
txb.addOutput(embed.output, 0);
}
// transaction 中增加转账地址和转账数量
txb.addOutput(this.to, stoAmount);
// remain = unspent balance - transfer amount - transfer fee
const remain = this.balance - stoAmount - sto2btc.toSatoshi(this.fee);
if (remain > 0) {
// 如果转账之后有剩余 加入最后的未花费列表
txb.addOutput(this.address, remain);
}
// 第一次钱包签名
res.unspent_outputs.forEach((item, i) => {
txb.sign(i, boss, p2sh.redeem.output);
});
console.log(txb);
const tx = txb.build();
this.rawData = tx.toHex();
console.log(this.rawData);
this.txId = tx.getId();
// 将第一次签名 rawData push 给后端, 从而通知其他单签账户参与签名
if (this.first === true) {
this.createBackend();
}
}
// 多签转账后续签名
// 将 btc 数量转 聪
const stoAmount = sto2btc.toSatoshi(this.amount);
// 获取当前参与多签的单签钱包账户权限
const boss = bitcoin.ECPair.fromWIF(this.privateKey, bitcoin.networks.bitcoin);
let txb = null;
let tx = null;
// 获取服务端发送过来存储在store中的上一个交易信息
const mulTx = JSON.parse(this.$store.state.tx.transfer);
// 多签转账后续更新签名 先将之前tx信息注入
tx = bitcoin.Transaction.fromHex(mulTx.Signatures);
txb = bitcoin.TransactionBuilder.fromTransaction(tx, bitcoin.networks.bitcoin);
// 自己钱包参与签名
txb.__inputs.forEach((item, i) => {
txb.sign(i, boss, item.redeemScript);
});
// rebuild所有钱包签名信息
const txNew = txb.build();
this.rawData = txNew.toHex();
console.log(this.rawData);
this.txId = txNew.getId();
// 多签转账后续更新签名 如果是最后一次签名 直接广播交易
if (this.isLast === true) {
this.publish();
} else {
this.updateBackend();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment