没有返回值
No values being returned
通过 Remix 使用 Ethereum 和 solidity 探索区块链,我遇到了这段代码:
pragma solidity ^0.8.1;
contract AccountsDemo{
address public whoDeposited;
uint public depositAmt;
uint public accountBalance;
function deposit() public payable{
whoDeposited = msg.sender;
depositAmt = msg.value;
accountBalance += address(this).balance
}
}
根据我使用的书,调用 deposit
应该导致 accountBalance
和 depositAmt
增加。当我尝试时,没有任何反应。交易记录在区块链上,但没有增加。这本书使用旧版本的 solidity - 0.6.0 不确定这是否是我沮丧的原因。
知道我在这里遗漏了什么吗?
您当前的存款功能是做什么的:
whoDeposited = msg.sender;
将发件人地址存储到属性 whoDeposited
。请注意,每次执行 deposit()
函数时,whoDeposited
的值都会被覆盖。
depositAmt = msg.value;
将交易值存储到属性 depositAmt
。请注意,每次执行 deposit()
函数时,depositAmt
的值都会被覆盖。
accountBalance += address(this).balance
增加 属性 accountBalance
的当前合约余额。当前合约余额 (address(this).balance
) 已经反映了执行 deposit()
函数时发送的交易值。
所以如果你的合约已经有 10 wei 的余额,accountBalance
是 10,现在你发送 2 wei...在执行期间,address(this).balance
现在是 12(因为2 wei,你发送),然后 accountBalance += 12
,这是你不想要的结果。
顺便说一下,您的代码段存在语法错误,并且由于行尾缺少分号而无法编译。
为了实现你的目标 - 将当前合约余额存储在 depositAmt
和 accountBalance
中(因此它们总是具有相同的值,也与 address(this).balance
相同),你可以这样做:
depositAmt += msg.value;
accountBalance = address(this).balance;
我切换了 +=
和 =
运算符。所以现在,当您向 deposit()
函数发送一个值时:
whoDeposited = msg.sender;
行为与上述相同。
depositAmt += msg.value;
每次执行deposit()
函数,depositAmt
的值都会增加交易的价值。这有效地反映了您合约的当前余额。
accountBalance = address(this).balance;
每次执行deposit()
函数,都会将accountBalance
的值设置为当前合约余额。当前合约余额已经反映了您在当前交易中发送的价值。
注意:我在这个回答中多次使用了“总是”这个词。并非总是如此 - 有一些边缘情况,例如从 selfdestruct
函数或在合约部署之前为你的合约地址提供资金,其中 address(this).balance
将与你的 depositAmt
不同并且accountBalance
。但最有可能的是,您一开始不会遇到这些边缘情况,因此您现在可以“始终”考虑它。很高兴知道在某些情况下此代码段无法按预期工作。
通过 Remix 使用 Ethereum 和 solidity 探索区块链,我遇到了这段代码:
pragma solidity ^0.8.1;
contract AccountsDemo{
address public whoDeposited;
uint public depositAmt;
uint public accountBalance;
function deposit() public payable{
whoDeposited = msg.sender;
depositAmt = msg.value;
accountBalance += address(this).balance
}
}
根据我使用的书,调用 deposit
应该导致 accountBalance
和 depositAmt
增加。当我尝试时,没有任何反应。交易记录在区块链上,但没有增加。这本书使用旧版本的 solidity - 0.6.0 不确定这是否是我沮丧的原因。
知道我在这里遗漏了什么吗?
您当前的存款功能是做什么的:
whoDeposited = msg.sender;
将发件人地址存储到属性
whoDeposited
。请注意,每次执行deposit()
函数时,whoDeposited
的值都会被覆盖。depositAmt = msg.value;
将交易值存储到属性
depositAmt
。请注意,每次执行deposit()
函数时,depositAmt
的值都会被覆盖。accountBalance += address(this).balance
增加 属性
accountBalance
的当前合约余额。当前合约余额 (address(this).balance
) 已经反映了执行deposit()
函数时发送的交易值。所以如果你的合约已经有 10 wei 的余额,
accountBalance
是 10,现在你发送 2 wei...在执行期间,address(this).balance
现在是 12(因为2 wei,你发送),然后accountBalance += 12
,这是你不想要的结果。顺便说一下,您的代码段存在语法错误,并且由于行尾缺少分号而无法编译。
为了实现你的目标 - 将当前合约余额存储在 depositAmt
和 accountBalance
中(因此它们总是具有相同的值,也与 address(this).balance
相同),你可以这样做:
depositAmt += msg.value;
accountBalance = address(this).balance;
我切换了 +=
和 =
运算符。所以现在,当您向 deposit()
函数发送一个值时:
whoDeposited = msg.sender;
行为与上述相同。
depositAmt += msg.value;
每次执行
deposit()
函数,depositAmt
的值都会增加交易的价值。这有效地反映了您合约的当前余额。accountBalance = address(this).balance;
每次执行
deposit()
函数,都会将accountBalance
的值设置为当前合约余额。当前合约余额已经反映了您在当前交易中发送的价值。
注意:我在这个回答中多次使用了“总是”这个词。并非总是如此 - 有一些边缘情况,例如从 selfdestruct
函数或在合约部署之前为你的合约地址提供资金,其中 address(this).balance
将与你的 depositAmt
不同并且accountBalance
。但最有可能的是,您一开始不会遇到这些边缘情况,因此您现在可以“始终”考虑它。很高兴知道在某些情况下此代码段无法按预期工作。