timezone |
---|
Asia/Shanghai |
- zhouCode,参加完一周前的协议学习,收获很多,这次继续狠狠地学习!
- 你认为你会完成本次残酷学习吗?会
- 你的联系方式(zhouG1n)
已知区块链有众多节点,每个节点都要保存完整的区块(理论上),但是每时每刻都在发生交易,这就导致每个节点实际上并不能真正的同时保存完全一致的内容,总会有一些节点先保存一部分数据。也就是传播延迟(propagation delay)
在POW时期,有可能出现2个矿工同时发现合法区块的情况,就会导致暂时分叉(temporal fork)一个称为主链,另一个称为叔父区块(uncles),叔父区块也会获得部分奖励。
POS机制中,新区块由投票决定,且区块的提议者由随机或者预先设定的调度机制选出,所以大大降低了多区块同时产生的可能性。由于只有一个指定的区块提议者负责出块,再加上更高效的共识和出块协调机制,网络中几乎不会出现由于传播延迟而导致的竞争性出块现象,因此也就没有了叔块的概念。
DApp
去中心化应用(DApp) 一般由两部分组成:
- 用户看到的前端界面(比如网页);
- 后台运行的智能合约(区块链上的程序)。
大多数 DApp(约 75%)的前端是用 JavaScript 写的网页,需要频繁和区块链网络交互。不过,由于前端本身不在链上,它需要通过 以太坊节点 提供的 RPC 接口 来和区块链沟通。
举个实际例子:
假设一个众筹 DApp 的前端想要显示用户的捐款记录,它会调用 eth_getLogs
方法获取数据;当用户发起新捐款时,前端则通过 eth_sendTransaction
方法提交交易,更新链上状态。
但直接操作节点有两个大问题:
- 参数容易出错: RPC 方法的参数格式很麻烦,比如要求「20 字节的十六进制地址」或「32 字节的十六进制字符串数组」,普通人很容易输错。
- 没有实时通知功能: 区块链的交易确认时间不确定(比如可能几秒或几分钟),但节点不会主动通知前端「交易是否完成」。用户只能反复调用方法(比如不停查余额)才能知道结果,非常低效。
所以实际开发中,DApp 会用现成的 JavaScript 工具库(比如 ethers.js、web3.js)。这些工具做了两件事:
- 自动把参数转换成正确的格式(比如地址补全 0x 前缀);
- 提供「回调通知」功能(比如交易成功后自动触发更新界面)。
前端(用户界面)在发起交易时,首先通过两个方法(getAccounts
和getTransactionCount
)获取两类信息:
- 用户拥有的钱包地址;
- 该地址已完成的交易次数(称为
nonce
,类似交易流水号)。
接着,它会调用 send
方法向后台的 ERC20 智能合约发送一笔“铸造代币”的交易请求。如果交易成功,系统会返回一个交易凭证。
这里的关键点在于:每次成功交易后,nonce
必须自动加 1。如果 nonce
值错误(比如重复或跳过),可能导致交易被直接拒绝,或者长时间卡在等待状态。
但问题在于:用户可能无意中连接到不同的区块链节点服务(RPC 服务)。如果某个节点返回的 nonce
值不准确(比如比其他节点少 1),就会引发上述问题。这种情况下,即使代码逻辑正确,也会因为节点数据不同步而导致交易异常。