Stellar交易创建与签名【JS Stellar SDK】

Stellar交易是可以改变账本状态的命令,包括支付、创建委托单、修改账户配置等。每个交易 都有一个源账户负责支付交易手续费并占用一个交易序列号。一个Stellar交易包含一个或多个操作, 每个操作都有一个源账户,默认为交易的源账户。

相关区块链教程/开发包推荐:以太坊 | 比特币 | EOS | Tendermint Core | Hyperledger Fabric | Omni/USDT | Ripple

1、Stellar交易构造器

JS Stellar SDK的TransactionBuilder类用来构建新的交易,其构造函数需要指定一个账户 作为交易的源账户。当TransactionBuilderbuild()方法被调用时,将递增源账户的交易 序列号。

可以使用addOperatioins()方法向Stellar交易对象中添加操作。你可以查看operation.js 中列出的可用操作,该方法返回当前的TransactionBuilder对象,因此你可以链式执行该方法多次。

在添加了期望的操作后,调用build()方法生成Stellar交易,该交易中将包含 所指定源账户的交易序列号。该交易是未签名的,在发送到Stellar网络之前必须先进行签名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// StellarBase.Network.usePublicNetwork(); 使用Stellar主链

// 使用指定地址和序列号创建Stellar账号对象
var account=new StellarBase.Account(
"GD6WU64OEP5C4LRBH6NK3MHYIA2ADN6K6II6EXPNVUR3ERBXT4AN4ACD",
"2319149195853854"
);

var transaction = new StellarBase.TransactionBuilder(account, {
fee: StellarBase.BASE_FEE,
networkPassphrase: Networks.TESTNET
})
// 添加支付操作
.addOperation(StellarBase.Operation.payment({
destination: "GASOCNHNNLYFNMDJYQ3XFMI7BYHIOCFW3GJEOWRPEGK2TDPGTG2E5EDW",
asset: StellarBase.Asset.native(),
amount: "100.50" // 100.50 XLM
}))
// 添加选项配置操作
.addOperation(StellarBase.Operation.setOptions({
signer: {
ed25519PublicKey: secondAccountAddress,
weight: 1
}
}))
// 设置交易超时
.setTimeout(30)
.build();

2、Stellar交易序列号

Stellar交易中的序列号必须与交易源账户的序列号一致,否则交易被视为无效。 在交易被提交并应用到账本后,源账户的序列号会加1。

有两个方法可以确保得到正确的序列号:

  • 在提交交易之前读取员账户的序列号
  • 本地管理序列号

在交易吞吐量处于高位时,从网络中提取源账户的序列号可能不会返回正确的值。 因此,如果你在高频提交大量交易,应该在本地跟踪序列号。

3、在Stellar交易中添加备注信息

Stellar交易中可以包含一个memo字段用来附加额外的备注信息。可以在创建 TransactionBuilder时传入一个备注对象。有5种类型的备注对象:

  • Memo.none:空的备注
  • Memo.text:28字节ascii编码的字符串备注
  • Memo.id:64字节的数值备注
  • Memo.hash:32字节哈希,例如内容服务器上某个条目的哈希
  • Memo.returnHash:32字节哈希,用于被拒绝交易
1
2
3
4
5
6
7
8
9
10
11
12
13
var memo = Memo.text('Happy birthday!');
var transaction = new StellarBase.TransactionBuilder(account, {
memo: memo,
fee: StellarBase.BASE_FEE,
networkPassphrase: Networks.TESTNET
})
.addOperation(StellarBase.Operation.payment({
destination: "GASOCNHNNLYFNMDJYQ3XFMI7BYHIOCFW3GJEOWRPEGK2TDPGTG2E5EDW",
asset: StellarBase.Asset.native(),
amount: "2000"
}))
.setTimeout(30)
.build();

4、将base64码流转换为Stellar交易对象

你可能不希望直接实例化交易对象,因为通常都是使用TransactionBuilder来创建Stellar交易对象。 然而,你也可以使用base64编码的交易封包来创建一个新的交易对象。

1
var transaction = new Transaction(envelope);

一旦交易从封包中创建出来,其属性和操作就不应该再变化。在将该交易提交到Stellar网络之前, 你应该只为该交易对象添加签名。

最重要的是,你可以使用sign()方法签名一个交易对象,详见下面说明。

5、Stellar交易的签名

Stellar交易需要签名以便用于身份认证,通常在一个Stellar交易中只需要一个签名。但是你可以 通过增加交易需要的签名来是实现更复杂的验证控制,我们将在后续文章中介绍多重签名机制。

可以使用交易对象的sign()方法为Stellar交易添加签名,同样,可以链式调用sign()方法多次。

Keypair类用来表示在Stellar网络中用于签名交易的密钥对。一个Keypair对象中可以包含 一个公钥和一个私钥,或者仅包含公钥。

如果Keypair对象不包含私钥,那么你就不能用它来签名交易。创建新的密钥对的最方便 的方法是传入账户的密文种子:

1
2
3
var keypair = Keypair.fromSecret('SBK2VIYYSVG76E7VC3QHYARNFLY2EAQXDHRC7BMXBBGIFG74ARPRMNQM');
var address = keypair.publicKey(); // GDHMW6QZOL73SHKG2JA3YHXFDHM46SS5ZRWEYF5BCYHX2C5TVO6KZBYL
var canSign = keypair.canSign(); // true

你可以使用密文种子的原始字节码流来创建Keypair对象:

1
2
3
4
5
6
var keypair = Keypair.fromRawSeed([
0xdc, 0x9c, 0xbf, 0xb5, 0xd7, 0x12, 0x83, 0x6a, 0xbf, 0x7d, 0x5d,
0xd8, 0xc4, 0xc4, 0x3e, 0x9d, 0xc7, 0x81, 0x85, 0xf1, 0x4b, 0x12,
0x0e, 0x9b, 0x59, 0x5d, 0x62, 0x65, 0x52, 0xa8, 0xcb, 0xcc]);
var address = keypair.publicKey(); // GADMPH2LB7VDK4UHNGKMJIJBXC5WTWTQMXYWSPVWPMNVVR4MGWLI2IXN
var canSign = keypair.canSign(); // true

你也可以创建一个随机生成的密钥对:

1
var keypair = Keypair.random();

有了包含私钥的密钥对,就可以签名交易了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var key1 = Keypair.fromSecret('SBK2VIYYSVG76E7VC3QHYARNFLY2EAQXDHRC7BMXBBGIFG74ARPRMNQM');
var key2 = Keypair.fromSecret('SAMZUAAPLRUH62HH3XE7NVD6ZSMTWPWGM6DS4X47HLVRHEBKP4U2H5E7');

// 使用指定地址和序列号创建Account对象
var account=new StellarBase.Account(
"GD6WU64OEP5C4LRBH6NK3MHYIA2ADN6K6II6EXPNVUR3ERBXT4AN4ACD","2319149195853854"
);

var transaction = new StellarBase.TransactionBuilder(account, {
fee: StellarBase.BASE_FEE,
networkPassphrase: Networks.TESTNET
})
.addOperation(StellarBase.Operation.payment({
destination: "GASOCNHNNLYFNMDJYQ3XFMI7BYHIOCFW3GJEOWRPEGK2TDPGTG2E5EDW",
asset: StellarBase.Asset.native(),
amount: "2000" // 2000 XLM
}))
.setTimeout(30)
.build();

transaction.sign(key1);
transaction.sign(key2);
// 将交易对象提交到Horizon API服务

原文链接:JS Stellar Base - Building Transactions

汇智网翻译整理,转载请标明出处