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:地址类型,以太坊合约的基础。有成员变量 balance
和 transfer
address x = 0x123;
#查询ETH余额
x.balance
#向地址x发送ETH
x.transfer(_value)
内置的三种数据结构 结构体 Structs结构体内的变量可以是任意类型
struct Holders {
address _address;
uint ethValue;
uint tokenValue;
uint id;
}
数组 Arraysuint[] 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的,也就是不能存款,需要在合约里声明 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);
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)