Ethereum 关于我创建的智能合约的几个问题(刚刚开始学习)

Ethereum 关于我创建的智能合约的几个问题(刚刚开始学习),ethereum,solidity,smartcontracts,Ethereum,Solidity,Smartcontracts,我刚开始学习solidity,对我为pratice/fun创建的智能合约有一些疑问。 请让我知道,如果我的任何概念是不准确的,感谢所有的建议和建议 说明: 这个智能合约的概念非常简单,谁向合约中发送的以太数量越多,谁就赢了,它会将你与你之前的任何人配对(如果没有人在你之前,你就是玩家),在2名玩家玩完之后,它会重置(这样就可以再次玩) 代码: contract zero_one { address public player_one; address public player_two; ui

我刚开始学习solidity,对我为pratice/fun创建的智能合约有一些疑问。 请让我知道,如果我的任何概念是不准确的,感谢所有的建议和建议

说明

这个智能合约的概念非常简单,谁向合约中发送的以太数量越多,谁就赢了,它会将你与你之前的任何人配对(如果没有人在你之前,你就是玩家),在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;
}
}
contract zero\u one{
向公众发表演说;
向公众发表演说(二),;
单位公共玩家数量;
uint公共播放器两个数量;
函数zero_one()公共{
重置();
}
函数play()公共支付{
//场景#1游戏中已经有两名玩家,不要接纳新玩家。我甚至需要这个检查吗?因为智能合约是连续执行的,所以我不应该面对这种情况?
if(player_-one!=地址(0)&player_-two!=地址(0))抛出;
//场景#2第一个玩家进入游戏
else if(player_-one==地址(0)和&player_-two==地址(0)){
player_one=msg.sender;
player\u one\u amount=msg.value;
}
//场景#3秒玩家加入,执行游戏
否则{
player_two=msg.sender;
player\u two\u amount=msg.value;
//检查玩家1和玩家2发送的金额,金额较大的人获胜并获得他们的钱
如果(玩家数量>玩家数量){
球员转会(球员转会金额+球员转会金额);
重置();
}
否则,如果(玩家两个)
将乙醚发送回用户时,我需要计算多少气体
还是智能合约会自动扣除汽油
从我将要发送的金额

执行交易时指定的天然气限额需要涵盖所有端到端的活动。这包括调用其他合同、转让等。交易开采后未使用的任何天然气将返还给您

将reset()设置为interal是否正确,因为我只希望它是interal 在智能合约中调用,任何人都不应该调用它 否则

internal
对于您打算做的事情来说是很好的。但是,它更像是
受保护的
访问。分包合同可以调用
internal
方法。
private
提供了最严格的可见性

情景1会发生吗?从我的理解来看 合同不必担心比赛条件,也不应该担心 你处于那种状态吗

不,这不应该发生。事务是按顺序处理的,这是正确的,因此您不必担心竞争条件。但这并不意味着您的代码中不应该有这种保护

添加播放是否正确?(因为用户将发送 (与此通话)

是的。任何希望接收wei并使用
msg.value
的方法都需要标记为
应付

使用投掷是一种不好的练习吗?(混音警告)

throw
已弃用。从0.4.13开始,您希望使用
revert
require
assert
中的一种。您使用的一种取决于您正在进行的检查类型以及是否应该退还汽油。有关详细信息,请参阅

传输与发送,为什么使用传输更好

send
transfer
类似。区别在于
send
限制了发送给呼叫的气体量,因此如果接收合同试图执行任何逻辑,它很可能会耗尽气体并失败。此外,
send
期间的故障不会传播错误,只会返回
错误

我把这个智能合约编码为一种实践。我已经看到如果 如果有人想玩这个系统,他可以等着别人来 player_one并检查player_one发送的数量(在阻塞完成后 (采矿)然后寄一笔比这更大的钱。还有这个吗 可以阻止利用漏洞?是否有其他我没有看到的安全/缺陷

安全性是一个更深入的话题。交易中发送的任何数据都是可见的,因此除非您使用私有区块链,否则您无法隐藏您提到的漏洞。您可以自己加密交易中发送的数据,但我不相信您可以加密发送数据


就其他安全问题而言,有几种工具可以对合同执行安全检查。我建议研究其中一种。此外,请通读Solidity文档上的页面。

Hi@Adam Kipnis,最后一个与安全相关的问题。智能合同是否可能知道它何时被开采?例如要修复该漏洞,是否有方法以以下方式对智能合约进行编码。--如果只有一名玩家在场,则在区块被开采时没收并返还金钱(确保只有两名玩家参与游戏)我是否正确理解答案1:谁触发了游戏()此合约中的函数必须发送足够的气体来提供play()将要触发的所有动作(包括将资金发回玩家的部分)。智能合约本身不需要提供任何气体,因为用户应该提供气体(如果没有提供足够的气体,智能合约将抛出)再次感谢您的回复:)“如果只有一个玩家在场,…”。我不确定我是否理解您的问题。
play()
需要在您的合同中调用两次,在两个不同的交易中,从两个不同的账户中挖掘(可能在不同的区块中的不同时间)。如果您想对第二名玩家的加入施加时间限制,您可以在您的代码中强制执行。对于您关于gas的第二条评论,您有通用i