一个简单的solidity代码

该文章描述了一个使用Solidity编写的简单众筹智能合约,合约利用了ERC20接口,实现了以太币购买代币的功能。合约包含了众筹目标、时间限制、代币价格等关键参数,并在达到目标或过期后处理资金。此外,还提供了安全退出机制,允许未达成目标时投资者撤回资金。
摘要由CSDN通过智能技术生成
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
//此时可以使用 import "./interface/IERC20.sol";但由于SimpleCrowdsale 只使用到了如下3个方法,而定义之
interface Itoken{
    function decimals() external view returns (uint8);
    function transfer(address recipient, uint amount) external returns (bool);
    function balanceOf(address account) external view returns (uint);
}
/**
 * 众筹合约
 */
contract SimpleCrowdsale  {
    //受益人地址, 构造函数传入的是合约的创建者,但也可以指定不同的受益地址
    address  public immutable beneficiary; 
    //发行代币的地址
    address  public token;
    //发行代币的地址精度
    uint8 public decimals;
    //众筹目标,单位是ether
    uint public fundingGoal; 
    //已筹集金额数量, 单位是ether 
    uint public amountRaised;
    //截止时间
    uint public deadline;
    //代币价格
    uint public price;
    //是否达成众筹目标
    bool public fundingGoalReached = false; 
    //众筹关闭
    bool public crowdsaleClosed = false; 

    //保存众筹地址及对应的以太币数量
    mapping(address => uint256) public balance;
    //保存所有众筹地址
    address[] public fundingList;

    // 受益人将众筹金额转走的通知
    event GoalReached(address _beneficiary, uint _amountRaised);

    // 用来记录众筹资金变动的通知,_isContribution表示是否是捐赠,因为有可能是捐赠者退出或发起者转移众筹资金
    event FundTransfer(address _backer, uint _amount, bool _isContribution);

    /**
     * @param fundingGoalInEthers 众筹以太币总量
     * @param durationInDays 众筹截止,单位是天
     * @param _token 奖励代币地址
     */
    constructor(uint fundingGoalInEthers,uint durationInDays,address _token) {
        beneficiary=msg.sender;
        fundingGoal = fundingGoalInEthers * 1 ether;
        deadline = block.timestamp + durationInDays * 1 days; //最后换算出来是秒
        price = 0.5 ether; 
        token=_token;
        decimals=Itoken(_token).decimals();
    }


    /**
     * 默认函数,可以向合约直接打款
     */
    receive() external payable 
    {
      buyToken();
    }
    //购买代币
    function buyToken() public payable
    {
        //判断是否关闭众筹
        require(!crowdsaleClosed,"Crowdsale closeed");
        uint amount = msg.value;
        //转入amount 个ETH 根据price能买入多少个 ERC20 代币 
        uint tokenBuyAmount=amount / price * 10 ** uint256(decimals);
        Itoken _t=Itoken(token);
        //合约账号代币余额不足
        require(_t.balanceOf(address(this))>=tokenBuyAmount,"Crowsale contract token amount insufficient");
        require(_t.transfer(msg.sender,tokenBuyAmount),"Token transfer failed");
        //捐款人的金额累加
        balance[msg.sender] += amount;
        //捐款总额累加
        amountRaised += amount;
        fundingList.push(msg.sender);
        //转帐操作,转多少代币给捐款人
        emit FundTransfer(msg.sender, amount, true);
    }
    /**
     * 判断是否已经过了众筹截止限期
     */
    modifier afterDeadline() { if (block.timestamp >= deadline) _; }

    /**
     * 时间到期后,检测众筹目标是否已经达到,
     */
    function checkGoalReached() afterDeadline public {
        if (amountRaised >= fundingGoal){
            //达成众筹目标
            fundingGoalReached = true;
            emit GoalReached(beneficiary, amountRaised);
        }

        //关闭众筹
        crowdsaleClosed = true;
    }
    function getBalance() public view returns(uint)
    {
      return payable(this).balance;
    }

    /**
     * 资金去留处理
     * 检查是否达到了目标或时间限制,如果有,并且达到了资金目标,
     * 将全部金额发送给受益人。如果没有达到目标,每个贡献者都可以退出并撤资
     * 注:这里代码应该是限制了众筹时间结束且众筹目标没有达成的情况下才允许退出。如果去掉限制条件afterDeadline,应该是可以允许众筹时间还未到且众筹目标没有达成的情况下退出
     */
    function safeWithdrawal()  public payable afterDeadline {
        //如果没有达成众筹目标
        if (!fundingGoalReached) {
            //获取合约调用者已捐款余额
            uint amount = balance[msg.sender];

            if (amount > 0) {
                //返回合约发起者所有余额
                payable(msg.sender).transfer(amount);
                emit FundTransfer(msg.sender, amount, false);
                balance[msg.sender] = 0;
            }
        }

        //如果达成众筹目标,并且合约调用者是受益人
        if (fundingGoalReached && beneficiary == msg.sender) {
            //将所有捐款从合约中给受益人
            payable(beneficiary).transfer(amountRaised);
            emit FundTransfer(beneficiary,balance[msg.sender],false);
        }
    }
}

bin与abi:

abi:Application Binary Interface,应用二进制接口文件。合约说明

智能合约的接口描述,描述了字段名称、字段类型、方法名称、参数名称、参数类型、方法返回值类型等。

当合约被编译后,对应的abi文件也就确定了。流程是先编译成evm可以识别的bytecode(bin文件),同时生成abi文件,然后进行部署

如一个abi文件内容:

[{"inputs":[],"name":"a","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

对应的bin文件内容:

6000805461ff00191661010017905560c0604052600360809081526235363760e81b60a052600190610031908261010b565b5060408051808201909152600381526235363760e81b6020820152600290610059908261010b565b5034801561006657600080fd5b506101ca565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061009657607f821691505b6020821081036100b657634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561010657600081815260208120601f850160051c810160208610156100e35750805b601f850160051c820191505b81811015610102578281556001016100ef565b5050505b505050565b81516001600160401b038111156101245761012461006c565b610138816101328454610082565b846100bc565b602080601f83116001811461016d57600084156101555750858301515b600019600386901b1c1916600185901b178555610102565b600085815260208120601f198616915b8281101561019c5788860151825594840194600190910190840161017d565b50858210156101ba5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61018c806101d96000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80630dbe671f1461003b57806312a7b9141461005c575b600080fd5b6000546100489060ff1681565b604051901515815260200160405180910390f35b6100486000600260405160200161007391906100b7565b60405160208183030381529060405280519060200120600160405160200161009b91906100b7565b6040516020818303038152906040528051906020012014905090565b600080835481600182811c9150808316806100d357607f831692505b602080841082036100f257634e487b7160e01b86526022600452602486fd5b818015610106576001811461011b57610148565b60ff1986168952841515850289019650610148565b60008a81526020902060005b868110156101405781548b820152908501908301610127565b505084890196505b50949897505050505050505056fea2646970667358221220e0c6a43c71fe85bb31a72ffd77f8017c78dbbfd195073ed61a240085544c000564736f6c63430008110033

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值