solidity 5.0,remix测试(个人学习,欢迎指正)
msg(研究了好一会,感觉还是有点困惑)
- msg.sender —当前合约的调用者
(1) 部署合约的地址
(2)调用该合约的地址 - msg.value —随消息发送的 wei 的数量(其实并不太懂)
(1)随消息发送??? 什么类型的信息 ???
(2) msg.value随消息发送 ,发送到哪儿?
(3)在remix部署时,设置value,只要调用该命令之后,直接发送到账户余额 why????测试代码如下所示
pragma solidity >=0.4.21 <0.7.0;
contract TestMsgValue {
address owner;
uint fee = 32 wei;
event MsgValue(uint);
event Tansfer(address from, address to, uint count);
//如果不提前声明合约为payable 那么remix构造函数时将不能使用value赋予价值
constructor() public payable {
owner = msg.sender;
/* emit MsgValue(msg.value); */
}
function show() public payable returns (uint) {
/* require(msg.value >= fee);
owner.transfer(msg.value - fee); */
emit MsgValue(msg.value);
/* emit MsgValue(msg.value); */
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
function transferValue(address getValueAddress, uint count) public {
emit Tansfer(address(this), msg.sender, count);
msg.sender.transfer(count);
getBalance();
}
}
测试说明
- 如果不声明构造函数 payable 就会报错如下图
我暂时理解为----如果不将这个合约payable,那么合约在部署时,并不具有接受以太币的条件(感觉不太对)。 - 部署合约时,带入value值,只要调用合约函数,那么value自动进入合约地址,this.balance += value;
对于这个霸道操作不是很明白,为什么只要运行函数,操作该合约就会将value加入合约!难道我设置value之后,调用函数也是message,相应value就是其附带的值嘛?
当前进度思考
- 如果部署到以太坊上,这个实际过程是怎么样的?
- 可以通过函数直接对合约账户充值嘛?
- 测试deposit函数
值得记录的一些语法
-
比较相同
(1)abi.encode() …returns (bytes) 对给定参数进行编码
(2)abi.encodePacked() returns (byetes) 更加精确的方法计算调用数据
keccak256(abi.encodePacked(a, b)) 取代了keccak256(a, b); -
view 与event
如果函数声明为 view 类型,这种情况下要保证不修改状态。
下面的语句被认为是修改状态:
修改状态变量。
**产生事件**。 ----view 限制符下 event会失效!!
创建其它合约。
使用 selfdestruct。
通过调用发送以太币。
调用任何没有标记为 view 或者 pure 的函数。
使用低级调用。
使用包含特定操作码的内联汇编。
- this直接用作地址报错 (sol 5.0)
Invalid type for argument in function call. Invalid implicit conversion from contract TestMsgValue to address requested.
emit Tansfer(this, msg.sender, count);
解决方法: 显示类型转换address(this)
再次更新 2020.2.23
- 不通过remix设置value,直接初始化一个含有固定数量wei的合约;
这是在官方文档上找到的,现在已经不能使用了;
pragma solidity ^0.4.0;
contract B {
function B() public payable {}
}
contract A {
address child;
function test() public {
child = (new B).value(10)(); //construct a new B with 10 wei
}
}
基于solc 5.0的代码 测试通过
pragma solidity >=0.5.0 <0.7.0;
contract D {
uint x;
constructor(uint a) public payable {
x = a;
}
function getX() public view returns (uint) {
return x;
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
}
contract C {
D d ;
event getDAddress(D);
/* event getBalance(uint); */
constructor() public {
emit getDAddress(d);
d = new D(4); // 将作为合约 C 构造函数的一部分执行
emit getDAddress(d);
}
function createD(uint arg) public {
D newD = new D(arg);
emit getDAddress(newD);
}
function createAndEndowD(uint arg, uint amount) public payable {
//随合约的创建发送 ether
D newD = (new D).value(amount)();
emit getDAddress(newD);
}
function getbalance(D _d) public view returns (uint) {
return _d.getBalance();
}
function getX(D _d) public view returns (uint) {
return _d.getX();
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
}
(1)首先申明一个合约D变量,在部署C合约的时候,那么在部署C合约的时候,就会自动创建D合约实例对象
(2)并且通过createAndEndowD函数传入参数,(转入合约D),这样D合约就会存放一定数量的wei
(3)调用createAndEndowD函数时,预设置value值,(要不然会报错---没有存入,就不能转账)
(4)通过getBalance()可以获取C合约的账户余额,通过getbalance()可以获取到D合约的账户余额(地址可以通过event事件获得)
- msg.value确实会出发命令将预设置的值传递进入合约;(remix环境中,预设置value值,下一条命令的执行就会将值转入合约内部) ---- 正式环境使用待补充