关于我创建的智能合约的几个问题(刚刚开始学习)
Few questions about smart contract I created (just start learning)
我刚开始学习 solidity,对我为 pratice/fun 创建的智能合约有一些疑问。
如果我的任何概念不准确,请告诉我,感谢所有的意见和建议。
描述:
这个智能合约的概念非常简单,谁向合约中发送更多的以太币,谁就获胜,它将把你和你之前的人配对(如果没有人在你之前,你就是 player_one) 并且会在 2 个播放器播放后重置(因此可以再次播放)
代码:
contract zero_one {
address public player_one;
address public player_two;
uint public player_one_amount;
uint public player_two_amount;
function zero_one() public{
reset();
}
function play() public payable{
//Scenario #1 Already have two player in game, dont accpet new player. do I even need this check at all? since smart contract execute serially i should never face this condition?
if(player_one != address(0) && player_two != address(0)) throw;
//Scenario #2 First player enter the game
else if(player_one == address(0) && player_two == address(0)){
player_one=msg.sender;
player_one_amount = msg.value;
}
//Scenario #3 Second player join in, execute the game
else{
player_two = msg.sender;
player_two_amount = msg.value;
//check the amount send from player_one and player two, whoever has the bigger amount win and get their money
if(player_two_amount>player_one_amount){
player_one.transfer(player_one_amount+player_two_amount);
reset();
}
else if(player_two_amount<player_one_amount){
player_two.transfer(player_one_amount+player_two_amount);
reset();
}
else{
//return fund back to both player
player_one.transfer(player_one_amount);
player_two.transfer(player_two_amount);
reset();
}
}
}
function reset() internal{
player_one = address(0);
player_two = address(0);
player_one_amount = 0;
player_two_amount = 0;
}
}
问题
回发以太币给用户的时候需要计算多少
天然气要采取?或者智能合约会自动扣除
我要发送的 gas
将 reset() 设置为 interal 是否正确,因为我只希望它是
在智能合约中调用,不应被其他任何人调用
场景#1 会发生吗?因为据我了解
智能合约不必担心竞争条件,它
永远不应该处于那种状态?
- 添加播放器播放正确吗? (因为用户将通过此调用发送以太币)
使用 throw 是一种不好的做法吗? (混音警告)
传输 vs 发送,为什么使用传输更好?
我把这个智能合约编码为练习。我已经可以看到如果
有人想玩这个系统,他可以等待某人成为 player_one 并检查 player_one 发送的数量(在开采区块后),然后发送比这更大的金额。无论如何,这个漏洞可以被阻止吗?还有其他的security/flaws我没看到吗?
谢谢!
When sending ether back to users, do I need to calcualate how much gas
is going to take? or would smart contract automatically deduct the gas
from the amount i am going to send
执行交易时指定的gas limit需要覆盖所有activity端到端。这包括调用其他合约、转账等。在交易被开采后未使用的任何 gas returned 给你。
Is it correct to set reset() as interal since i only want it to be
called within the smart contract, it shouldn't be called by anyone
else
internal
很适合您打算做的事情。但是,它更像是 protected
访问。一个子合约可以调用 internal
方法。 private
提供最严格的可见性。
Would Scenario#1 ever happen? since from what I understand smart
contract do not have to worry about race condition and it should never
be in that state?
不,这不应该发生。你是正确的,事务是串行处理的,所以你真的不必担心竞争条件。这并不意味着您的代码中不应该有这种保护...
Is adding playable to play correct? ( since user are going to send
ether with this call)
是的。任何期望接收 wei 并使用 msg.value
的方法都需要标记为 payable
.
Is using throw a bad practice? (warning on remix)
throw
已弃用。从 0.4.13 开始,您想使用 revert
、require
、assert
之一。您使用的支票类型取决于您进行的支票类型以及是否应退还汽油。有关详细信息,请参阅 this。
transfer vs send, why is it better to use transfer?
send
和transfer
是相似的。不同之处在于 send
限制了发送给调用的 gas 量,因此如果接收合约试图执行任何逻辑,它很可能 运行 耗尽 gas 并失败。此外,send
期间的失败不会传播错误,而只是 return false
。 Source
I coded this smart contract as a practice. I can already see that if
someone want to game the system, he could just wait for someone to be
player_one and check the amount player_one send(after the block is
mined) and just send a bigger sum than that. Is there anyway this
exploit could be stopped? Is there other security/flaws I did not see?
安全是一个更深入的话题。交易中发送的任何数据都是可见的,因此除非您使用私有区块链,否则您无法隐藏您提到的漏洞。你可以自己加密交易中发送的数据,但我不相信你可以加密发送以太币。
就其他安全问题而言,有几种工具可以对合约执行安全检查。我建议调查其中一个。此外,请通读 Solidity 文档中的 security considerations 页面。
我刚开始学习 solidity,对我为 pratice/fun 创建的智能合约有一些疑问。 如果我的任何概念不准确,请告诉我,感谢所有的意见和建议。
描述:
这个智能合约的概念非常简单,谁向合约中发送更多的以太币,谁就获胜,它将把你和你之前的人配对(如果没有人在你之前,你就是 player_one) 并且会在 2 个播放器播放后重置(因此可以再次播放)
代码:
contract zero_one {
address public player_one;
address public player_two;
uint public player_one_amount;
uint public player_two_amount;
function zero_one() public{
reset();
}
function play() public payable{
//Scenario #1 Already have two player in game, dont accpet new player. do I even need this check at all? since smart contract execute serially i should never face this condition?
if(player_one != address(0) && player_two != address(0)) throw;
//Scenario #2 First player enter the game
else if(player_one == address(0) && player_two == address(0)){
player_one=msg.sender;
player_one_amount = msg.value;
}
//Scenario #3 Second player join in, execute the game
else{
player_two = msg.sender;
player_two_amount = msg.value;
//check the amount send from player_one and player two, whoever has the bigger amount win and get their money
if(player_two_amount>player_one_amount){
player_one.transfer(player_one_amount+player_two_amount);
reset();
}
else if(player_two_amount<player_one_amount){
player_two.transfer(player_one_amount+player_two_amount);
reset();
}
else{
//return fund back to both player
player_one.transfer(player_one_amount);
player_two.transfer(player_two_amount);
reset();
}
}
}
function reset() internal{
player_one = address(0);
player_two = address(0);
player_one_amount = 0;
player_two_amount = 0;
}
}
问题
回发以太币给用户的时候需要计算多少 天然气要采取?或者智能合约会自动扣除 我要发送的 gas
将 reset() 设置为 interal 是否正确,因为我只希望它是 在智能合约中调用,不应被其他任何人调用
场景#1 会发生吗?因为据我了解 智能合约不必担心竞争条件,它 永远不应该处于那种状态?
- 添加播放器播放正确吗? (因为用户将通过此调用发送以太币)
使用 throw 是一种不好的做法吗? (混音警告)
传输 vs 发送,为什么使用传输更好?
我把这个智能合约编码为练习。我已经可以看到如果 有人想玩这个系统,他可以等待某人成为 player_one 并检查 player_one 发送的数量(在开采区块后),然后发送比这更大的金额。无论如何,这个漏洞可以被阻止吗?还有其他的security/flaws我没看到吗?
谢谢!
When sending ether back to users, do I need to calcualate how much gas is going to take? or would smart contract automatically deduct the gas from the amount i am going to send
执行交易时指定的gas limit需要覆盖所有activity端到端。这包括调用其他合约、转账等。在交易被开采后未使用的任何 gas returned 给你。
Is it correct to set reset() as interal since i only want it to be called within the smart contract, it shouldn't be called by anyone else
internal
很适合您打算做的事情。但是,它更像是 protected
访问。一个子合约可以调用 internal
方法。 private
提供最严格的可见性。
Would Scenario#1 ever happen? since from what I understand smart contract do not have to worry about race condition and it should never be in that state?
不,这不应该发生。你是正确的,事务是串行处理的,所以你真的不必担心竞争条件。这并不意味着您的代码中不应该有这种保护...
Is adding playable to play correct? ( since user are going to send ether with this call)
是的。任何期望接收 wei 并使用 msg.value
的方法都需要标记为 payable
.
Is using throw a bad practice? (warning on remix)
throw
已弃用。从 0.4.13 开始,您想使用 revert
、require
、assert
之一。您使用的支票类型取决于您进行的支票类型以及是否应退还汽油。有关详细信息,请参阅 this。
transfer vs send, why is it better to use transfer?
send
和transfer
是相似的。不同之处在于 send
限制了发送给调用的 gas 量,因此如果接收合约试图执行任何逻辑,它很可能 运行 耗尽 gas 并失败。此外,send
期间的失败不会传播错误,而只是 return false
。 Source
I coded this smart contract as a practice. I can already see that if someone want to game the system, he could just wait for someone to be player_one and check the amount player_one send(after the block is mined) and just send a bigger sum than that. Is there anyway this exploit could be stopped? Is there other security/flaws I did not see?
安全是一个更深入的话题。交易中发送的任何数据都是可见的,因此除非您使用私有区块链,否则您无法隐藏您提到的漏洞。你可以自己加密交易中发送的数据,但我不相信你可以加密发送以太币。
就其他安全问题而言,有几种工具可以对合约执行安全检查。我建议调查其中一个。此外,请通读 Solidity 文档中的 security considerations 页面。