首页 > 区块链 > 区块链 > Solidity之旅(十三)函数及其可见性和状态可变性
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract stateVarsVisible {
uint public num;
function showNum() public returns(uint){
num += 1;
return num;
}
}
contract outsideCall {
function myCall() public returns(uint){
//实例化合约
stateVarsVisible sv = new stateVarsVisible();
//调用 getter 函数
return sv.num();
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract stateVarsVisible {
uint internal num;
function showNum() public returns(uint){
num += 1;
return num;
}
function fn() external returns(uint){
return num;
}
}
contract sub is stateVarsVisible {
function myNum() public returns(uint){
return stateVarsVisible.num;
}
}
contract outsideCall {
function myCall() public returns(uint){
//实例化合约
stateVarsVisible sv = new stateVarsVisible();
//外部合约 不能访问
//return sv.num();
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract stateVarsVisible {
uint private num;
function showNum() public returns(uint){
num += 1;
return num;
}
function fn() external returns(uint){
return num;
}
}
contract sub is stateVarsVisible {
function myNum() public returns(uint){
//派生合约 无法访问 基合约 的状态变量
return stateVarsVisible.num;
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract FunctionVisible {
uint private num;
function privateFn(uint x) private returns(uint y){ y = x + 5; }
function setNum(uint x) public { num = x;}
function getNum() public returns(uint){ return num; }
function sum(uint x,uint y) internal returns(uint) { return x + y; }
function showPri(uint x) external returns(uint){ x += num; return privateFn(x); }
}
contract Outside {
function myCall() public {
FunctionVisible fv = new FunctionVisible();
uint res = fv.privateFn(7); // 错误:privateFn 函数是私有的
fv.setNum(4);
res = fv.getNum();
res = fv.sum(3,4); // 错误:sum 函数是 内部的
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract FunctionVisible {
uint private num;
function privateFn(uint x) private view returns(uint y){ y = x + num; }
function setNum(uint x) public { num = x;}
function getNum() public view returns(uint){ return num; }
function sum(uint x,uint y) internal pure returns(uint) { return x + y; }
function showPri(uint x) external view returns(uint){ x += num; return privateFn(x); }
}
contract Sub is FunctionVisible {
function myTest() public pure returns(uint) {
uint val = sum(3, 5); // 访问内部成员(从继承合约访问父合约成员)
val = privateFn(6); //privateFn函数是私有的,即便是派生合约也不能访问
return val;
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract C {
uint public data;
function x() public returns(uint) {
data = 3; // 内部访问
uint val = this.data(); // 外部访问
return val;
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract C {
uint[] public myArray;
// 自动生成的Getter 函数
/*
function myArray(uint i) public view returns (uint) {
return myArray[i];
}
*/
// 返回整个数组
function getArray() public view returns (uint[] memory) {
return myArray;
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
function sum(uint[] memory arr) pure returns (uint s) {
for (uint i = 0; i < arr.length; i++)
s += arr[i];
}
contract ArrayExample {
bool found;
function f(uint[] memory arr) public {
//编译器会将 合约外函数的代码添加到这里
uint s = sum(arr);
require(s >= 10); //后续会讲到
found = true;
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Simple {
uint sum;
function taker(uint a, uint b) public {
sum = a + b;
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Simple {
function arithmetic(uint a, uint b) public pure returns (uint sum, uint product)
{
sum = a + b;
product = a * b;
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Simple {
function arithmetic(uint a, uint b)
public
pure
returns (uint , uint )
{
return (a + b, a * b);
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Simple {
function f(uint a, uint b) public view returns (uint) {
return a * (b + 42) + block.timestamp;
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Simple {
function f(uint a, uint b) public pure returns (uint) {
return a * (b + 42);
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Simple {
event Received(address, uint);
receive() external payable {
emit Received(msg.sender, msg.value);
}
}
(c, d) = abi.decode(_input[4:], (uint256, uint256));
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Test {
// 发送到这个合约的所有消息都会调用此函数(因为该合约没有其它函数)。
// 向这个合约发送以太币会导致异常,因为 fallback 函数没有 `payable` 修饰符
fallback() external { x = 1; }
uint x;
}
// 这个合约会保留所有发送给它的以太币,没有办法返还。
contract TestPayable {
uint x;
uint y;
// 除了纯转账外,所有的调用都会调用这个函数.
// (因为除了 receive 函数外,没有其他的函数).
// 任何对合约非空calldata 调用会执行回退函数(即使是调用函数附加以太).
fallback() external payable { x = 1; y = msg.value; }
// 纯转账调用这个函数,例如对每个空empty calldata的调用
receive() external payable { x = 2; y = msg.value; }
}
contract Caller {
function callTest(Test test) public returns (bool) {
(bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));
require(success);
// test.x 结果变成 == 1。
// address(test) 不允许直接调用 send , 因为 test 没有 payable 回退函数
// 转化为 address payable 类型 , 然后才可以调用 send
address payable testPayable = payable(address(test));
testPayable.transfer(2 ether);
// 以下将不会编译,但如果有人向该合约发送以太币,交易将失败并拒绝以太币。
// test.send(2 ether);
return true;
}
function callTestPayable(TestPayable test) public returns (bool) {
(bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));
require(success);
// 结果 test.x 为 1 test.y 为 0.
(success,) = address(test).call{value: 1}(abi.encodeWithSignature("nonExistingFunction()"));
require(success);
// 结果test.x 为1 而 test.y 为 1.
// 发送以太币, TestPayable 的 receive 函数被调用.
// 因为函数有存储写入, 会比简单的使用 send 或 transfer 消耗更多的 gas。
// 因此使用底层的call调用
(success,) = address(test).call{value: 2 ether}("");
require(success);
// 结果 test.x 为 2 而 test.y 为 2 ether.
return true;
}
}
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70012206/viewspace-3000991/ ,如需转载,请注明出处,否则将追究法律责任。