1703877558
1703877559
如果一个钱包与互联网相联,则称其为在线钱包。例如,在geth中存储的钱包、任何网站/数据库等都称为在线钱包。在线钱包也称为热钱包、Web钱包、托管钱包等。不推荐使用在线钱包,至少在存储大量以太币或者长期存储以太币时不推荐使用,因为有风险。而且根据钱包存储位置的不同,它还可能要求信任第三方。
1703877560
1703877561
例如,最热门的钱包服务本身存储钱包私钥,并允许用户通过e-mail和密码访问钱包,所以用户基本上不会实质性地访问钱包,如果有人想偷,就能偷钱包里的钱。
1703877562
1703877563
如果一个钱包不与互联网相联,则称其为离线钱包。例如,存储在闪存盘、纸张、文本文件等中的钱包。离线钱包也称为冷钱包。离线钱包比在线钱包更安全,因为要偷钱的人必须能够访问物理内存。离线存储的问题是,用户需要找到一个不会意外删除或者忘记的位置,或者让其他任何人都不能访问的位置。如果想长期安全地保管钱款,许多人会在纸上存储钱包,然后把纸放入保险箱。如果想从账户频繁地发送钱款,则可以存在带有密码保护的闪存盘和保险箱里。用数字设备存储钱包有点危险,因为数字设备可能随时坏掉,那样就无法访问钱包了。这就是为什么既要存在闪存盘中,还应当存在保险箱里。根据需求的不同,用户还可以找到更好的解决方法,但是必须确保方法安全,且不会意外地丢失对钱包的访问路径。
1703877564
1703877565
1703877566
1703877567
1703877569
区块链项目开发指南 5.2 Hooked-Web3-Provider和EthereumJS-tx库
1703877570
1703877571
到目前为止,Web3.js库的sendTransaction()方法的所有例子都使用以太坊节点出现的from地址,因此以太坊节点能够在广播之前签署交易。但是如果用户把钱包的私钥存储在其他地方,geth就发现不了它。因此在这种情况下,需要使用web3.eth.sendRawTransaction()方法广播交易。
1703877572
1703877573
web3.eth.sendRawTransaction()用于广播原始交易,也就是说,用户不得不编写代码来创建和签署原始交易。以太坊节点将直接广播,而不对交易做任何其他操作。但是使用web3.eth.sendRawTransaction()编写代码以广播交易并非易事,因为它要求生成数据部分、创建原始交易并签署交易。
1703877574
1703877575
Hooked-Web3-Provider库提供自定义程序提供方(custom provider),它使用HTTP与geth通信。这个提供方的独特之处在于,它允许使用密钥签署合约实例的sendTransaction()调用,因此不再需要创建交易的数据部分了。自定义程序提供方事实上重写了web3.eth.sendTransaction()方法的实现,所以基本上它允许签署合约实例的sendTransaction()调用以及web3.eth.sendTransaction()调用。合约实例的sendTransaction()方法在内部生成交易数据,并调用web3.eth.sendTransaction()广播交易。
1703877576
1703877577
EthereumJS是一系列与以太坊相关的库。EthereumJS-tx是其中之一,它提供了多种与交易相关的API,例如,允许创建原始交易、签署原始交易、检查交易是否正确使用密钥进行了签名,等等。
1703877578
1703877579
这两个库对node.js和客户端JavaScript可用。访问https://www.npmjs.com/package/hooked-web3-provider可下载Hooked-Web3-Provider,访问https://www.npmjs.com/package/ethereumjs-tx可下载EthereumJS-tx。
1703877580
1703877581
在写本书时,Hooked-Web3-Provider的最新版本是1.0.0,EthereumJS-tx的最新版本是1.1.4。
1703877582
1703877583
下面来看如何使用这些库从一个不由geth管理的账户发送交易。
1703877584
1703877585
1703877586
1703877587
1703877588
上述代码的执行过程如下:
1703877589
1703877590
1)创建一个HookedWeb3Provider实例(由Hooked-Web3-Provider库提供)。该构造函数有一个对象,这个对象有两个必须提供的属性host和transaction_signer。host是节点的HTTP URL,transaction_signer是自定义服务提供方用于签署交易的通信对象。
1703877591
1703877592
2)transaction_signer对象有两个属性hasAddress和signTransaction。调用hasAddress检查交易是否可以签署,即检查交易签署者是否有from地址账户的私钥。该方法接收地址和一个回调函数。如果找不到地址私钥,回调函数的第一个实参应当是错误信息,第二个实参应当是false;如果找到地址私钥,第一个实参应当是null,第二个实参应当是true。
1703877593
1703877594
3)如果发现地址私钥,则自定义程序提供方调用signTransaction方法得到交易签名。该方法有两个参数,即交易参数和回调函数。在这个方法中,首先将交易参数转换为原始交易参数,也就是说,将原始交易参数数值编译为十六进制的字符串。然后创建一个缓存存储私钥。缓存使用EthJS.Util.toBuffer()方法创建,该方法是EthereumJS-util库的一部分。EthereumJS-util库由EthereumJS-tx库导入。接下来创建一个原始交易并签名,之后编序号,并转换成十六进制字符串。最后需要用回调函数为自定义服务提供方提供签名原始交易的十六进制字符串。该方法发生错误时,回调函数的第一个实参应当是一个错误信息。
1703877595
1703877596
4)自定义服务提供方进行原始交易,并用web3.eth.sendRawTransaction()进行广播。
1703877597
1703877598
5)调用web3.eth.sendTransaction函数向另一个账户发送若干以太币。这里需要提供nonce以外的所有交易参数,因为自定义服务提供方可以计算nonce。此前,许多参数都是可选项,因为把它们留给了以太坊节点进行计算,但是由于这里要自己签署,就需要提供所有交易参数。如果交易没有任何相关数据,则gas总是21000。
1703877599
1703877600
1703877601
公钥的情况呢?
1703877602
1703877603
在上述代码中,并未提及签署地址的公钥。如果矿工没有公钥,该如何验证交易的真实性?矿工使用了ECDSA算法的一个独特属性,该属性允许矿工通过信息和签名计算公钥。在交易中,信息表示交易意向,签名用于发现签署信息时是否使用了正确的私钥。这是ECDSA算法的独特之处。EthereumJS-tx提供一个API用于验证交易。
1703877604
1703877605
1703877606
1703877607
[
上一页 ]
[ :1.703877558e+09 ]
[
下一页 ]