【问题标题】:Few questions about smart contract I created (just start learning)关于我创建的智能合约的几个问题(刚开始学习)
【发布时间】:2018-06-16 11:10:51
【问题描述】:

我刚开始学习 Solidity,并且对我为练习/娱乐而创建的智能合约有一些疑问。 如果我的任何概念不准确,请告诉我,感谢所有建议和建议。

说明

这个智能合约的概念很简单,谁给合约发送更多的以太币谁就赢了,它会和你之前的人配对(如果没有人在你之前,你就是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;
}
}

问题

  • 将以太币发回给用户时,我需要计算多少 气要走?还是智能合约会自动扣除 我要发送的气体量

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

  • 场景#1 会发生吗?因为据我了解 智能合约不必担心竞态条件和它 永远不应该处于那种状态?

    1. 添加可播放内容是否正确? (因为用户将通过此调用发送以太币)
  • 使用 throw 是一种不好的做法吗? (混音警告)

  • transfer vs send,为什么使用transfer更好?

  • 我将此智能合约编码为一种实践。我已经可以看到,如果 有人想玩系统,他可以等待某人成为 player_one 并检查 player_one 发送的金额(在区块被开采后),然后发送比这更大的金额。无论如何,这个漏洞可以被阻止吗?还有其他我没有发现的安全/缺陷吗?

谢谢!

【问题讨论】:

    标签: ethereum solidity smartcontracts


    【解决方案1】:

    向用户发送以太币时,我需要计算多少gas 会拿吗?还是智能合约会自动扣除gas 从我要发送的金额开始

    执行交易时指定的gas限制需要端到端覆盖所有活动。这包括调用其他合约、转账等。任何在交易被挖掘后未使用的 gas 都将退还给您。

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

    internal 可以满足您的需求。但是,它更像是protected 访问。分包合约可以调用internal 方法。 private 提供最严格的可见性。

    场景#1 会发生吗?因为据我所知聪明 合同不必担心比赛条件,它不应该 处于那种状态?

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

    添加可播放内容是否正确? (因为用户要发送 以太与此调用)

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

    使用 throw 是一种不好的做法吗? (混音警告)

    throw 已弃用。从 0.4.13 开始,您想使用 revertrequireassert 之一。您使用哪一种取决于您进行的检查类型以及是否应退还汽油。详情请见this

    transfer vs send,为什么使用transfer更好?

    sendtransfer 是相似的。不同之处在于send 限制了发送给调用的 gas 量,因此如果接收合约试图执行任何逻辑,它很可能会耗尽 gas 并失败。此外,send 期间的故障不会传播错误并简单地返回falseSource

    我将此智能合约编码为一种实践。我已经可以看到,如果 有人想玩系统,他可以等着有人来 player_one 并检查 player_one 发送的数量(在块被 开采的)并且只发送比这更大的金额。反正有这个吗 可以阻止漏洞利用吗?还有其他我没有发现的安全/缺陷吗?

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

    在其他安全问题方面,有几种工具可以对合约执行安全检查。我建议调查其中之一。另外,请阅读 Solidity 文档中的 security considerations 页面。

    【讨论】:

    • 嗨@Adam Kipnis,关于安全的最后一个问题。智能合约是否有可能知道它何时被开采?例如,要修复漏洞,有没有办法通过以下方式对智能合约进行编码。 ---如果只有player_one,则在挖出块时没收并返还钱(确保只有两个玩家时才能玩游戏)
    • 我是否正确理解了答案 1 如下:在这个合约中触发 play() 函数的人必须发送足够的 gas 来供应 play() 将触发的所有动作。 (包括将资金返还给玩家的部分)。智能合约本身不需要提供任何气体,因为假设用户提供它(如果没有提供足够的气体,智能合约将抛出)
    • 再次非常感谢您的回复:)
    • “如果只有 player_one 存在,...”。不确定我是否理解你的问题。 play() 需要在您的合约中在来自 2 个不同账户的 2 个独立交易中调用两次(可能在不同区块的不同时间)。如果您想对第二名玩家的加入施加时间限制,您可以在您的代码中强制执行。
    • 关于气体的第二条评论,你有一个大致的想法。一般来说,你不会在play()进行转账。您将计算欠一个地址的金额并将其存储在您的合同状态中。然后,将使用单独的withdraw() 方法来收集奖金。见solidity.readthedocs.io/en/develop/common-patterns.html
    猜你喜欢
    • 1970-01-01
    • 2019-10-16
    • 2022-09-22
    • 2021-07-21
    • 2023-01-20
    • 2012-10-12
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多