目录

Solidity 源代码要成为可以运行在以太坊上的智能合约需要经历如下的步骤

Solidity编译器

Remix

solcjs

问题:Warning: SPDX license identifier not provided in source file

问题:TypeError: Data location must be “memory” or “calldata” for parameter in function, but none was give

案例一

案例二


Solidity 源代码要成为可以运行在以太坊上的智能合约需要经历如下的步骤

  1. 用 Solidity 编写的智能合约源代码需要先使用编译器编译为字节码( Bytecode ),编译过程中会同时产生智能合约的二进制接口规范( Application Binary Interface ,简称 ABI );
  2. 通过交易( Transaction )的方式将字节码部署到以太坊网络,每次成功部署都会产生产生一个新的智能合约账户
  3. 使用 Javascript 编写的 DApp 通常通过 web3.js + ABI 去调用智能合约中的函数来实现数据的读取和修改

Solidity编译器

Remix

  • Remix 是一个基于 Web 浏览器的 Solidity IDE;可在线使用而无需安装任何东西
  • http://remix.ethereum.org

solcjs

  • solc 是 Solidity 源码库的构建目标之一,它是 Solidity 的命令行编译器
  • 使用 npm 可以便捷地安装 Solidity 编译器 solicjs
npm install -g solc# -g是全局安装,也可以不加自己选择目的文件夹

问题:Warning: SPDX license identifier not provided in source file

问题:Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing “SPDX-License-Identifier: ” to each source file. Use “SPDX-License-Identifier: UNLICENSED” for non-open-source code. Please see https://spdx.org for more information.

原因:从 Solidity ^0.6.8 引入 SPDX 许可证。所以你需要在代码中使用SPDX-License-Identifier

解决方案:在.sol文件第一句加上

// SPDX-License-Identifier: MIT

问题:TypeError: Data location must be “memory” or “calldata” for parameter in function, but none was give

原因:这是由于solidity 0.5.0版本的更新导致的,只需要在用到 string 的时候,在后面加上 memory 就可以了

解决方法:

案例一

// SPDX-License-Identifier: MIT// pragma solidity >0.4.22 <0.5.0;pragma solidity ^0.8.3;contract SimpleStorage{    uint myData;    function setData(uint newData) public{        myData = newData;        }    // 返回值类型需要加上 returns + 返回值类型, 例如 returns(uint)    // view 表示只读不写    function getData() public view returns(uint){        return myData;    }    // 返回两个数    function pureAdd(uint a,uint b) public pure returns(uint sum, uint _a){        return (a + b, a);    }}

案例二

// SPDX-License-Identifier: MITpragma solidity ^0.8.3;contract Car{    string brand;       // 车牌    uint public price;     // 价格    // 构造函数,合约创建时自动调用    constructor(string memory initBrand,uint initPrice){        brand = initBrand;        price = initPrice;    }    function setBrand(string memory newBrand) public {        brand = newBrand;    }    function getBrand() public view returns(string memory){        return brand;    }    function setPrice(uint newPrice) public {        price = newPrice;    }}

案例三

// SPDX-License-Identifier: MITpragma solidity ^0.8.3;contract Coin{    address public minter;  // 铸币者    mapping(address => uint) public balances;    // 所有账号    event Sent(address from,address to,uint amount);   /**    * 功能: 初始化    */    constructor(){        minter = msg.sender;    }   /**    * 功能: 铸币    * @param receiver    * @param amount    */    function mint(address receiver, uint amount) public{        // 调用铸币的人必须是规定的铸币人        require(msg.sender == minter);        // 铸币人的 账户余额 += amount        balances[receiver] += amount;    }   /**    * 功能: 发币    * @param receiver    * @param amount    */    function send(address receiver, uint amount) public{        // msg.sender 代表调用这个函数的人        // 发币人的账户要大于等于 amount        require(balances[msg.sender] >= amount);        // 发币人的 账户余额 -= amount        balances[msg.sender] -= amount;        // 接收人的 账户余额 += amount        balances[receiver] += amount;        emit Sent(msg.sender, receiver, amount);    }}

案例四

// SPDX-License-Identifier: MITpragma solidity ^0.8.3;contract Try{    uint public a;    uint public b;    uint[] public data;    function f() public{        uint[] storage x = data;        x.push(2);        data = x;    }}contract FakeHoneyPot{    uint public luckyNum = 12;    struct Guess{        address player;        uint number;    }    Guess[] guessHistory;    address owner = msg.sender;    function guess(uint _num) public payable{        guessHistory.push(Guess({            player:msg.sender,            number:_num        }));        if(_num == luckyNum){            payable(msg.sender).transfer(msg.value * 2);        }    }}