区块链开发:如何从 Solidity 智能合约中发送和取款

区块链开发:如何从 Solidity 智能合约中发送和取款

在本文中,将展示一个智能合约的示例,可以向该智能合约发送交易,验证其余额,然后仅当调用该函数的地址是所有者时才将资金提取到一个地址,通常称为所有者模型。

与所有者创建智能合约

好的,首先要做的事情是:创建一个新文件,将其命名为 MySmartContract.sol(或者理想情况下,想要的任何名称)并添加许可证和 Solidity 版本语句,如下所示:

然后在下面创建一个地址变量来存储合约的所有者:

接下来,将创建一个构造函数,将部署合约的地址存储为所有者。构造函数是一个特殊函数,仅在部署合约时调用一次。将使用 msg 对象的 sender 属性。msg.sender 是一个内置变量,用于存储在任何给定时间与智能合约交互的地址。

// SPDX-License-Identifier:GPL-3.0
pragma solidity
contract MySmartContract {
    // owner of this contract
    address public contractOwner;
    // constructor is called during contract deployment
    constructor(){
        // assign the address that is creating
        // the transaction for deploying contract
        contractOwner = msg.sender'
    }
}

继续保存合约,编译和部署。点击 contractOwner 按钮,可以看到部署合约的地址现在是 owner 了。

向智能合约汇款

接下来,将创建一个函数,允许任何地址向合约汇款。

// SPDX-License-Identifier:GPL-3.0
pragma solidity
contract MySmartContract {
    // owner of this contract
    address public contractOwner;
    // constructor is called during contract deployment
    constructor(){
        // assign the address that is creating
        // the transaction for deploying contract
        contractOwner = msg.sender'
    }

    function sendMoneyToContract() public payable {}
    function getBalance() public view returns(uint){
        return address(this).balance;
    }
}

使用关键字 payable 来指定函数可以接收以太币。

在 getBalance 函数中,关键字 this 指的是这个特定的合约(MySmartContract)。

现在将继续部署合约并测试是否可以将以太币发送到合约并检查合约的余额。

从智能合约中提取所有资金

现在,创建一个 withdrawAll 函数来传递希望汇款的地址。

// SPDX-License-Identifier:GPL-3.0
pragma solidity
contract MySmartContract {
    // owner of this contract
    address public contractOwner;
    // constructor is called during contract deployment
    constructor(){
        // assign the address that is creating
        // the transaction for deploying contract
        contractOwner = msg.sender'
    }

    function sendMoneyToContract() public payable {}
    function getBalance() public view returns(uint){
        return address(this).balance;
    }
    function withdrawAll(address payable _to) public {
        _to.transfer(address(this).balance);
    }
}

当部署和测试合约时,会注意到任何人都可以运行这个 withdrawAll 函数,这是不安全的,下面增加限制只允许 sendcontract 所有者执行此功能。使用 require 来检查条件,如果条件不满足则抛出异常。

在这种情况下,检查调用函数的地址是否与合约所有者相同。如果失败,它将回滚事务。该合约现在满足 Owner 模型,在该模型中,它检查调用函数的地址是否是所有者,然后才允许它继续进行。

// SPDX-License-Identifier:GPL-3.0
pragma solidity
contract MySmartContract {
    // owner of this contract
    address public contractOwner;
    // constructor is called during contract deployment
    constructor(){
        // assign the address that is creating
        // the transaction for deploying contract
        contractOwner = msg.sender'
    }

    function sendMoneyToContract() public payable {}
    function getBalance() public view returns(uint){
        return address(this).balance;
    }
    function withdrawAll(address payable _to) public {
        require(contractOwner == _to);
        _to.transfer(address(this).balance);
    }
}

这就是这个简单的智能合约,它允许向它发送资金,并且只允许所有者从智能合约中提取所有资金。