如果智能合约存储在区块链中的区块上,它的状态是如何更新的?
If smart contracts are stored on blocks in the blockchain, how is its state updated?
我了解智能合约被转换为字节码并存储在区块链中的一个块上。可以像 Kickstarter 一样使用智能合约。项目团队可能会设定一个资金目标,只有在支持者捐赠足够的资金来实现目标时才会支付该目标。
但是智能合约如何知道何时向项目团队付款?一个块的哈希值会根据其数据发生巨大变化。因此,不可能跟踪区块内的捐赠数量和交易 ID,因为这会改变区块的哈希值。因此,智能合约如何知道已经资助了多少钱,如果没有达到资助目标,它又如何记住将钱捐给哪里?
真的有账本(或区块链)和状态数据库吗?
如果是这样,我假设我们将与智能合约相关联的值存储在状态数据库中。
智能合约的字节码在交易(在区块中挖掘)中发布,然后存储在与地址关联的网络(通常是以太坊或币安智能链)的存储中。
因此,每次与智能合约交互时,您都在与一个地址交互,该地址与包含字节码的存储块相关联。加上字节码指向存储其变量值的其他存储槽。
所有状态变化(包括存储值的变化)都是账本数据库的一部分。原始区块链数据仅包含状态更改(不是当前状态),但大多数更高层 return 默认情况下是当前状态(您仍然可以选择获取较旧的状态,例如“defaultBlock”参数 here).有些层甚至不允许访问以前的状态(例如用于编写智能合约的 Solidity 和 Vyper 语言——您可以将此代码编译为字节码)。
But how does the the smart contract know when to pay the project team?
智能合约可以访问任何地址的当前余额,包括它自己的。它还可以有一个包含资金目标的变量。比较这两个值,告诉你目标是否达到,智能合约是否应该向项目组支付费用。
但是,智能合约目前没有任何本机计时器(例如 cronjobs)或事件处理程序 - 并且在将交易发送到智能合约的地址(data
字段事务说明了您要执行的功能以及您要传递的参数)。
因此您需要手动发送交易(执行 withdraw()
函数)或使用一些链下工具(可以查看当前余额,然后发送交易为您执行该函数)。
pragma solidity ^0.8;
contract MyContract {
uint256 constant FUNDING_GOAL = 1 ether;
address constant TEAM_ADDRESS = address(0x123);
/**
* Throws if the current balance is lower than the goal
* Otherwise sends all of the current balance to the predefined address
*
* Need to send transaction with correct value of the `data` field
* to execute this `withdraw()` function.
* Most client apps generate the correct value of `data` field for you
* after selecting the function name and specifying argument values.
*/
function withdraw() external {
require(address(this).balance >= FUNDING_GOAL, 'Haven\'t reached the funding goal');
payable(TEAM_ADDRESS).transfer(address(this).balance);
}
/**
* Allows this contract to receive native currency of the network (usually ETH or BNB)
*/
receive() external payable {}
}
我了解智能合约被转换为字节码并存储在区块链中的一个块上。可以像 Kickstarter 一样使用智能合约。项目团队可能会设定一个资金目标,只有在支持者捐赠足够的资金来实现目标时才会支付该目标。
但是智能合约如何知道何时向项目团队付款?一个块的哈希值会根据其数据发生巨大变化。因此,不可能跟踪区块内的捐赠数量和交易 ID,因为这会改变区块的哈希值。因此,智能合约如何知道已经资助了多少钱,如果没有达到资助目标,它又如何记住将钱捐给哪里?
真的有账本(或区块链)和状态数据库吗? 如果是这样,我假设我们将与智能合约相关联的值存储在状态数据库中。
智能合约的字节码在交易(在区块中挖掘)中发布,然后存储在与地址关联的网络(通常是以太坊或币安智能链)的存储中。
因此,每次与智能合约交互时,您都在与一个地址交互,该地址与包含字节码的存储块相关联。加上字节码指向存储其变量值的其他存储槽。
所有状态变化(包括存储值的变化)都是账本数据库的一部分。原始区块链数据仅包含状态更改(不是当前状态),但大多数更高层 return 默认情况下是当前状态(您仍然可以选择获取较旧的状态,例如“defaultBlock”参数 here).有些层甚至不允许访问以前的状态(例如用于编写智能合约的 Solidity 和 Vyper 语言——您可以将此代码编译为字节码)。
But how does the the smart contract know when to pay the project team?
智能合约可以访问任何地址的当前余额,包括它自己的。它还可以有一个包含资金目标的变量。比较这两个值,告诉你目标是否达到,智能合约是否应该向项目组支付费用。
但是,智能合约目前没有任何本机计时器(例如 cronjobs)或事件处理程序 - 并且在将交易发送到智能合约的地址(data
字段事务说明了您要执行的功能以及您要传递的参数)。
因此您需要手动发送交易(执行 withdraw()
函数)或使用一些链下工具(可以查看当前余额,然后发送交易为您执行该函数)。
pragma solidity ^0.8;
contract MyContract {
uint256 constant FUNDING_GOAL = 1 ether;
address constant TEAM_ADDRESS = address(0x123);
/**
* Throws if the current balance is lower than the goal
* Otherwise sends all of the current balance to the predefined address
*
* Need to send transaction with correct value of the `data` field
* to execute this `withdraw()` function.
* Most client apps generate the correct value of `data` field for you
* after selecting the function name and specifying argument values.
*/
function withdraw() external {
require(address(this).balance >= FUNDING_GOAL, 'Haven\'t reached the funding goal');
payable(TEAM_ADDRESS).transfer(address(this).balance);
}
/**
* Allows this contract to receive native currency of the network (usually ETH or BNB)
*/
receive() external payable {}
}