制定智能合约跟踪汇率并仅接受设定值的付款
Make a smart contract track exchange rate and only accept payments of a set value
我制定了一个接收付款的智能合约,然后将付款支付给另外 2 个地址,将收到的总价值分成 2 份,分别为 10% 和 90%。它将在网站上与付费专区一起使用。我刚才做了这个,它似乎有效(6 个月前在主网上发布,用于此页面:http://www.linebreakrecords.com/plaintext.php 不是一个严肃的商店更多只是我学习如何在网站上使用区块链)。然而,我使用的代码是基本的,现在有些地方已弃用(当我在 Remix 中查看时,我现在收到关于不使用 'emit prefixes and 'Potential Violation of Checks-Effects-Interaction pattern' 以及 'Fallback function...requires too much gas (infinite)' 的警告)。
首先,我希望获得有关如何使此代码更 robust/secure 并符合当前最佳实践的建议。其次,我希望就如何让合同只接受超过一定价值(例如 2 美元)的交易并跟踪当前汇率(这样我就可以将最低应付金额设置为 2 美元并使其遵循汇率所以无论市场变化如何,它都保持在 2 美元)。我知道这是非常基本的东西,我在这里给出的代码可能是原始的 AF,我正在努力学习,如果可以的话请帮忙。非常感谢。
pragma solidity ^0.4.15;
contract CONTRACT1{
event senderLogger(address);
event valueLogger(uint);
address person1Adress;
address person2Adress;
function () payable {
senderLogger(msg.sender);
valueLogger(msg.value);
person1Adress = 0x705b4e2d44be431740b11fa9ba6ace47bef8d035;
person1Adress.transfer(msg.value / 10);
person2Adress = 0xC0BB3c8362628E152f70b602de4B7CFB41516618;
person2Adress.transfer((msg.value / 10) * 9);
}
}
这不是一个糟糕的合同,但它肯定需要一些改进。我在下面指出了一些问题,但总会有更多问题。智能合约工作需要对测试有偏执的心态,因为你在用真钱工作,如果你搞砸了,就没有银行可以 reverse the transaction 给你(平价示例仍然是烧毁的 ETH,并且很可能会保持这种状态).
我希望这可以帮助您改进,如果您需要更多帮助,请告诉我!如果我的回答符合您的要求,请不要忘记打勾,这样您的问题才算是已解决。
制表符 ;)
- 帮帮我,伙计,很难阅读你的代码片段。
活动
- 想想活动的目的是什么。提醒您区块链上发生了一些事情。
- 如果是这样,当区块链上只发生 单个事件 时,为什么会发出两个事件,每个事件仅包含一条信息。
- 此外,在较新版本的 Solidity (https://solidity.readthedocs.io/en/v0.4.21/contracts.html#events) 中调用事件之前,您还需要
emit
并且它在旧版本中是允许的,因此不妨添加它以澄清它不是随机函数调用.
构造函数
- 初始化您将在合同 constructor 中分配资金的两个地址,而不是每次收到以太币时都初始化。
数学
- 你分钱的方式很吓人。您是否对此进行了测试并确保合约在每次交易后以 0 以太币结束?
- 在合同中除以 10 时,您可以对通常无法得出的数字做出一些很酷的假设。现在,将 Solidity 中的数字视为具有位数限制的十进制数字(它在位上但足够接近)。
- 所以我们限制在代码中没有小数的 5 位数字,但我们将数字解释为 3 位数字和 2 位小数。这使得
12525
125.25。 Solidity中125.25除以10就是把每一位都右移,前面加一个0。
- 这使得
125.25 / 10 = 12.52
和 12.52 * 9 = 112.68' but
12.52 + 112.68 = 125.2with .05 left in the contract untouched. Over time this may build up, but either way is burnt ether as you didn't include a function that calls the
selfdestruct()` 函数。
- 正确的计算方法是计算 90% 或 10%。然后从您收到的以太币数量中减去结果以找到要发送的其他值。在上面的例子中,你会做
125.25 - 12.52 = 112.73
并且没有余数。
- 对于大多数智能合约工作,您应该使用 SmartMath 来防止 over/under 流程出现问题。
气体预测
- 我很少看到这是正确的,所以在您查看后我会忽略它。
- 它通常是由于您的函数中存在循环或其他导致 Solidity 不知道您将使用多少 gas 的东西而触发的。
- 尽管如此,请始终检查它,因为您永远不知道是否有未终止的循环或其他问题。
- 虽然它可能不知道您的函数需要多少 gas,但关于回退函数的警告是绝对正确的。
- 如果回退函数需要的 gas 超过交易所需的最低 gas,它将失败,这是任何有经验的合约开发者都不会做的事情,所以要注意它。
- 不过,我的建议是不要乱用回退函数,我一直发现它们是一个毫无意义的功能(因为它们可以 运行 编码)而且我从不包括一个(让它如此不ether can't be sent to my contract 没有调用支付函数)。
- 只要您希望您的合约接收以太币并在之后执行某些功能,请随时使用支付功能。
- 如果你只是希望你的合约能够完成所有编码的事情并接收无意义的捐赠(有人只是想变得友善),那将是回退功能的用例。
- 但话又说回来,如果你有一个后备函数,以太坊的新手可能只是将以太币发送到你的合约而不是调用一个函数,你会把它当作捐赠。
- 这是我想要一个没有代码且简单存在的可支付捐赠函数的另一个原因,所以如果有人在没有函数调用的情况下向我的合约发送以太币,它会告诉他们它是无效的。
你想做什么
- Whosebug 通常反对这种事情,因此请尽量避免说出您想做的事情并期望我们为您做或解释如何做。
- 就个人而言,这是我最喜欢的编程部分,在较大的项目中,一旦它只是编写代码行并且所有问题都已解决(尽管每个问题都没有解决),我会感到不安。
- 相反,询问您对您正在尝试做的事情最困惑的部分。
- 我会像你问的那样回答:"So I want to only accept transactions above a certain value and have that value track to the exchange rate. How can I track the exchange rate?"
- 以防万一你不知道,拒绝发送到应付交易的以太币就像 require 条件错误一样简单。
- Require 很棒,因为大多数客户端甚至可以在之前检测到它
将交易发送给你,这样你就不会拒绝以太币,而是
相反,Metamask 告诉他们不要发送交易,因为
它会失败。
- 如果他们选择发送它,它仍然会失败并发回以太币
您无需再编写任何代码,但他们发送的气体会
被烧毁。
- 为了跟踪汇率,您确实需要以太坊上的某种 Oracle 或去中心化交易所来显示其价格 API(我不相信存在任何 rn)。
- 一个更有用的方法是手动设置汇率并每天更新。您可以将其设置为单击按钮,您的 JS 代码与 1000 价格中的任何一个交互 API 以获取价格,然后通过函数调用发送它。
- 这绝对不是一个完美的解决方案,但是从区块链外部获取信息到区块链中是一个相当大的挑战。查看 Oraclize 并查看它们提供的可以帮助您完成任务的内容。
我制定了一个接收付款的智能合约,然后将付款支付给另外 2 个地址,将收到的总价值分成 2 份,分别为 10% 和 90%。它将在网站上与付费专区一起使用。我刚才做了这个,它似乎有效(6 个月前在主网上发布,用于此页面:http://www.linebreakrecords.com/plaintext.php 不是一个严肃的商店更多只是我学习如何在网站上使用区块链)。然而,我使用的代码是基本的,现在有些地方已弃用(当我在 Remix 中查看时,我现在收到关于不使用 'emit prefixes and 'Potential Violation of Checks-Effects-Interaction pattern' 以及 'Fallback function...requires too much gas (infinite)' 的警告)。
首先,我希望获得有关如何使此代码更 robust/secure 并符合当前最佳实践的建议。其次,我希望就如何让合同只接受超过一定价值(例如 2 美元)的交易并跟踪当前汇率(这样我就可以将最低应付金额设置为 2 美元并使其遵循汇率所以无论市场变化如何,它都保持在 2 美元)。我知道这是非常基本的东西,我在这里给出的代码可能是原始的 AF,我正在努力学习,如果可以的话请帮忙。非常感谢。
pragma solidity ^0.4.15;
contract CONTRACT1{
event senderLogger(address);
event valueLogger(uint);
address person1Adress;
address person2Adress;
function () payable {
senderLogger(msg.sender);
valueLogger(msg.value);
person1Adress = 0x705b4e2d44be431740b11fa9ba6ace47bef8d035;
person1Adress.transfer(msg.value / 10);
person2Adress = 0xC0BB3c8362628E152f70b602de4B7CFB41516618;
person2Adress.transfer((msg.value / 10) * 9);
}
}
这不是一个糟糕的合同,但它肯定需要一些改进。我在下面指出了一些问题,但总会有更多问题。智能合约工作需要对测试有偏执的心态,因为你在用真钱工作,如果你搞砸了,就没有银行可以 reverse the transaction 给你(平价示例仍然是烧毁的 ETH,并且很可能会保持这种状态).
我希望这可以帮助您改进,如果您需要更多帮助,请告诉我!如果我的回答符合您的要求,请不要忘记打勾,这样您的问题才算是已解决。
制表符 ;)
- 帮帮我,伙计,很难阅读你的代码片段。
活动
- 想想活动的目的是什么。提醒您区块链上发生了一些事情。
- 如果是这样,当区块链上只发生 单个事件 时,为什么会发出两个事件,每个事件仅包含一条信息。
- 此外,在较新版本的 Solidity (https://solidity.readthedocs.io/en/v0.4.21/contracts.html#events) 中调用事件之前,您还需要
emit
并且它在旧版本中是允许的,因此不妨添加它以澄清它不是随机函数调用.
构造函数
- 初始化您将在合同 constructor 中分配资金的两个地址,而不是每次收到以太币时都初始化。
数学
- 你分钱的方式很吓人。您是否对此进行了测试并确保合约在每次交易后以 0 以太币结束?
- 在合同中除以 10 时,您可以对通常无法得出的数字做出一些很酷的假设。现在,将 Solidity 中的数字视为具有位数限制的十进制数字(它在位上但足够接近)。
- 所以我们限制在代码中没有小数的 5 位数字,但我们将数字解释为 3 位数字和 2 位小数。这使得
12525
125.25。 Solidity中125.25除以10就是把每一位都右移,前面加一个0。 - 这使得
125.25 / 10 = 12.52
和12.52 * 9 = 112.68' but
12.52 + 112.68 = 125.2with .05 left in the contract untouched. Over time this may build up, but either way is burnt ether as you didn't include a function that calls the
selfdestruct()` 函数。 - 正确的计算方法是计算 90% 或 10%。然后从您收到的以太币数量中减去结果以找到要发送的其他值。在上面的例子中,你会做
125.25 - 12.52 = 112.73
并且没有余数。 - 对于大多数智能合约工作,您应该使用 SmartMath 来防止 over/under 流程出现问题。
气体预测
- 我很少看到这是正确的,所以在您查看后我会忽略它。
- 它通常是由于您的函数中存在循环或其他导致 Solidity 不知道您将使用多少 gas 的东西而触发的。
- 尽管如此,请始终检查它,因为您永远不知道是否有未终止的循环或其他问题。
- 虽然它可能不知道您的函数需要多少 gas,但关于回退函数的警告是绝对正确的。
- 如果回退函数需要的 gas 超过交易所需的最低 gas,它将失败,这是任何有经验的合约开发者都不会做的事情,所以要注意它。
- 不过,我的建议是不要乱用回退函数,我一直发现它们是一个毫无意义的功能(因为它们可以 运行 编码)而且我从不包括一个(让它如此不ether can't be sent to my contract 没有调用支付函数)。
- 只要您希望您的合约接收以太币并在之后执行某些功能,请随时使用支付功能。
- 如果你只是希望你的合约能够完成所有编码的事情并接收无意义的捐赠(有人只是想变得友善),那将是回退功能的用例。
- 但话又说回来,如果你有一个后备函数,以太坊的新手可能只是将以太币发送到你的合约而不是调用一个函数,你会把它当作捐赠。
- 这是我想要一个没有代码且简单存在的可支付捐赠函数的另一个原因,所以如果有人在没有函数调用的情况下向我的合约发送以太币,它会告诉他们它是无效的。
你想做什么
- Whosebug 通常反对这种事情,因此请尽量避免说出您想做的事情并期望我们为您做或解释如何做。
- 就个人而言,这是我最喜欢的编程部分,在较大的项目中,一旦它只是编写代码行并且所有问题都已解决(尽管每个问题都没有解决),我会感到不安。
- 相反,询问您对您正在尝试做的事情最困惑的部分。
- 我会像你问的那样回答:"So I want to only accept transactions above a certain value and have that value track to the exchange rate. How can I track the exchange rate?"
- 以防万一你不知道,拒绝发送到应付交易的以太币就像 require 条件错误一样简单。
- Require 很棒,因为大多数客户端甚至可以在之前检测到它 将交易发送给你,这样你就不会拒绝以太币,而是 相反,Metamask 告诉他们不要发送交易,因为 它会失败。
- 如果他们选择发送它,它仍然会失败并发回以太币 您无需再编写任何代码,但他们发送的气体会 被烧毁。
- 为了跟踪汇率,您确实需要以太坊上的某种 Oracle 或去中心化交易所来显示其价格 API(我不相信存在任何 rn)。
- 一个更有用的方法是手动设置汇率并每天更新。您可以将其设置为单击按钮,您的 JS 代码与 1000 价格中的任何一个交互 API 以获取价格,然后通过函数调用发送它。
- 这绝对不是一个完美的解决方案,但是从区块链外部获取信息到区块链中是一个相当大的挑战。查看 Oraclize 并查看它们提供的可以帮助您完成任务的内容。