首页 > 解决方案 > 如果智能合约存储在区块链中的区块上,它的状态如何更新?

问题描述

我了解智能合约被转换为字节码并存储在区块链中的一个块中。智能合约可以与 Kickstarter 类似地使用。项目团队可能会设定一个资金目标,只有在支持者捐赠足够的资金来实现该目标时才会支付该目标。

但是智能合约如何知道何时向项目团队付款?一个块的哈希值会根据其数据发生巨大变化。因此,跟踪区块内的捐赠数量和交易 ID 应该是不可能的,因为它会改变区块的哈希值。因此,智能合约如何知道已经资助了多少钱,以及如果没有达到资助目标,它又如何记住将钱捐赠到哪里?

是否有分类账(或区块链)和状态数据库?如果是这样,我假设我们将与智能合约关联的值存储在状态数据库中。

标签: blockchainsmartcontractscryptocurrency

解决方案


智能合约的字节码在交易中发布(在区块中挖掘),然后存储在与地址关联的网络存储(通常是以太坊或币安智能链)中。

因此,每次与智能合约交互时,您都在与与包含字节码的存储块相关联的地址进行交互。加上字节码指向其他存储其变量值的存储槽。

所有状态更改(包括存储值的更改)都是分类帐数据库的一部分。原始区块链数据仅包含状态更改(不是当前状态),但大多数较高层默认返回当前状态(您仍然可以选择获取旧状态,例如此处的“defaultBlock”参数)。有些层甚至不允许访问以前的状态(例如,用于编写智能合约的 Solidity 和 Vyper 语言——您可以将此代码编译为字节码)。


但是智能合约如何知道何时向项目团队付款?

智能合约可以访问任何地址的当前余额,包括它自己的。它也可以有一个包含资助目标的变量。比较这两个值可以告诉你目标是否已经达到,智能合约是否应该支付给项目团队。

但是,智能合约目前没有任何本地计时器(例如 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 {}
}

推荐阅读