快速入门solidity

快速入门solidity,第1张

开发语言

solidity高级语言,专门用于开发智能合约,使用solc进行编译。

docs:深入理解Solidity — Solidity develop 文档

官方在线编译器:Remix - Ethereum IDE

solidity-GitHub:GitHub - ethereum/solidity: Solidity, the Smart Contract Programming Language

本地编译需要在本地安装solc,然后使用命令进行编译 bin 和 abi即可。solc在solidity的GitHub tag里找对应系统和对应版本下载即可。

智能合约运行原理

以太坊虚拟机(EVM)是以太坊上智能合约的运行环境。它实际上是完全隔离的,这意味着在EVM上运行的代码无法访问网络、文件系统和其他进程。

使用solidity编写智能合约使用EVM编译器编译成字节码元数据 通过交易上传部署到链上 合约的基本方法和变量 空合约结构

#pragma solidity >=0.6.0;

pragma solidity ^0.6.0;

contract MyFirst{

}

定义代码使用的Solidity编译器版本的声明,编译合约时必须使用版本号相符合的solc才可以编译。

方法修饰

function () {internal|external} [pure|constant|view|payable] [returns ()]

public:内部、外部均可见private:仅在当前合约内可见 external:仅在外部可见(仅可修饰函数)——就是说,仅可用于消息调用(即使在合约内调用,也只能通过 this.func 的方式)internal:仅在内部可见(也就是在当前 Solidity 源代码文件内均可见,不仅限于当前合约内,译者注)

pure 修饰函数时:不允许修改或访问状态——但目前并不是强制的。

view 修饰函数时:不允许修改状态——但目前不是强制的。

payable 修饰函数时:允许从调用中接收 以太币Ether 。

constant 修饰状态变量时:不允许赋值(除初始化以外),不会占据 存储插槽storage slot 。

constant 修饰函数时:与 view 等价。

anonymous 修饰事件时:不把事件签名作为 topic 存储。

indexed 修饰事件时:将参数作为 topic 存储。

常用变量类型 bool:true/falseint/uint:从 8 到 256位,uint8/int8...uint256/int256。int 和 int 分别是 uint256 和 int256 的别名 address:地址类型,以太坊合约的基础。有成员变量 balancetransfer

address x = 0x123;

#查询ETH余额

x.balance

#向地址x发送ETH

x.transfer(_value)

内置的三种数据结构 结构体 Structs

结构体内的变量可以是任意类型

struct Holders {

        address _address;

        uint ethValue;

        uint tokenValue;

        uint id;

}

数组 Arrays

uint[] numbers; //动态

uint[5] numbers; //编译时固定大小

映射 Mappings

映射可以看作是哈希表,key value的形式存在,可以快速的查找到指定key的内容。key和value几乎可以是任何类型。

代币合约中的代币数量就是使用mapping存储的,以address为键值,可快速的查询和修改余额

mapping(address => uint) public balances;

solidity开发常用知识点 权限验证

一般需要读取 msg.sender 变量,获取的是该笔交易的发起者,判断此调用者是否有对应的权限

合约中断方法

require(msg.sender==owner,"only owner")

判断合约调用者是不是合约的拥有者,当为true时才会继续执行合约,false时直接回滚整个交易,合约执行失败

或者使用 revert("only owner") 方法中断

合约接收ETH

合约默认是不能接收ETH的,也就是不能存款,需要在合约里声明 payable 才行

回退函数 function() public payable {}

或者在方法后面声明 payable,表示该方法可以转ETH

时间单位

默认是秒,可使用的单位有:seconds,minutes,hours,days,weeks,years

1 == 1 seconds

1 minutes == 60 seconds

1 hours == 60 minutes

1 days == 24 hours

1 weeks == 7 days

1 years == 365 days

不推荐使用 years 单位,因为有闰年 闰秒的原因

以太币单位

最小换算单位为 wei。还有 finney,szabo,ether,默认是wei

1 ether = 10^18 wei

1ether = 1000 finney

1ether = 1000000 szabo

合约的内联调用

合约内调用另一个合约的方法,通过接口Interface定义,创建实例调用合约方法。

合约中调用USDT合约的转账和查询余额

interface ERC20 {

    function balanceOf(address who) public constant returns (uint);

    function transfer(address to, uint value) public;

}

contract Test {

  ERC20 public token;

  function setToken(address token_addr) public {

     #创建实例

    token = ERC20(token_addr);

  }

  function inTransfer() public {

    #获取合约地址的余额

    uint value = token.balanceOf(address(this));

    #将合约的USDT发送到调用者地址

    token.transfer(msg.sender,value);

  }

合约内转移ETH方法

#将合约地址的ETH发送到调用者地址

msg.sender.transfer(value);

外部调用合约方法和查询变量

调起合约内需要作修改的方法就是发送一笔交易,需要花费gas。只查询不修改的方法或变量只需要call,不需要任何gas。

调起合约方法

合约的方法请求主要是data数据的构造,Function由MethodID和参数构成,methodID的计算方法:

hash256(funtion定义)【注:transfer(address,uint256),方法名和参数类型】的前十位,后面跟着参数的十六进制,每个参数占64字节,不足64位的前面补0,组成总的inputdata。

如:向地址 0x295aab7819f23e8f3d97ba8a29c50c38aa07119a,转95USDT的构造合约的transfer方法请求。

MethodID = hash(transfer(address,uint256)).substring(0,10) 【0xa9059cbb】

address = 000000000000000000000000295aab7819f23e8f3d97ba8a29c50c38aa07119a

95USDT 由于USDT币种精度是6位,也就是实际值是 95000000,转换成十六进制 = 5a995c0

uint256 = 0000000000000000000000000000000000000000000000000000000005a995c0

所以调用合约方法的data拼起来是:

0xa9059cbb000000000000000000000000295aab7819f23e8f3d97ba8a29c50c38aa07119a0000000000000000000000000000000000000000000000000000000005a995c0

查询合约静态变量

call有 view 或 constant修饰的方法,或者静态变量。data的构造和上面方法一样。

ERC20标准合约例子

所谓标准ERC20协议是指接口的标准化。

接口类

pragma solidity ^0.6.0;

interface IERC20 {

function totalSupply() external view returns (uint256);

function balanceOf(address account) external view returns (uint256);

function transfer(address recipient, uint256 amount) external returns (bool);

function allowance(address owner, address spender) external view returns (uint256);

function approve(address spender, uint256 amount) external returns (bool);

function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

event Transfer(address indexed from, address indexed to, uint256 value);

event Approval(address indexed owner, address indexed spender, uint256 value);

}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/944261.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-18
下一篇 2022-05-18

发表评论

登录后才能评论

评论列表(0条)

保存