是否可以仅从应用程序提供对智能合约的访问并阻止直接访问?

时间:2020-02-02 14:23:18

标签: ethereum solidity smartcontracts web3

例如,我有一个游戏,并且我希望玩家仅通过应用程序进行交互。但是,只要复制ABI和联系地址,他们就可以调用函数。

是否有任何情况允许使用某种秘密令牌仅通过应用程序调用公共合同功能?但是我不知道如何在公共区块链中制作这样的秘密令牌。

2 个答案:

答案 0 :(得分:2)

如果合同中包含与秘密令牌相关的逻辑,那么运行节点的任何人都可以看到该逻辑,因此这似乎很困难。

普通的Web服务器可以使用cookie和域名检查等方法来保护api,但是智能合约无法访问合约外的数据,并且合约内的数据是可见的,因此很难进行密码保护。

似乎只有可能的解决方案使用加密数字签名并使用代理服务器。
来自应用程序的代理服务器控制请求,并创建对智能合约的签名请求,该智能合约仅允许来自代理服务器的请求。

答案 1 :(得分:0)

(1)处理此问题的一种方法是自己签署交易,而不是让用户进行交易。您可以为函数onlyAdmin添加修饰符,并将应用程序的帐户地址指定为管理员。然后,如果其他任何人调用,这些函数将还原。

问题在于,您将需要付费并在游戏中拥有机制,以确保用户无法利用您的签名密钥。


function doSomething(bytes32 userId) public onlyAdmin {
  // ...
}

(2) 您可以做的另一件事是设置一个在函数中被散列的值,然后验证该散列。在游戏中,您可以为用户提供将通过验证的值,缺点是您每次使用后必须确保更新哈希值。

要执行此操作,您可以发出一个事件并进行监听,然后发送tx来更新appHash,但这会耗费您大量的精力,并且可能会导致计时攻击,具体取决于其余实现的内容。喜欢。

您还可以将功能设置为锁定状态,然后通过重置appHash将其解锁,但这又需要您的工作和精力。

bytes32 public appHash = '1s2a3d4g';

function doSomething(appSecret bytes32) public {
  require(keccak256(appSecret) == appHash);
  // ...
  emit didSomething(msg.sender, appSecret);
}

带锁

bytes32 public appHash = '1s2a3d4g';
bool public locked = false;

function doSomething(bytes32 appSecret) public {
  require(keccak256(appSecret) == appHash);
  require(locked == false);
  // ...
  locked = true;
}

function unlock(bytes32 nextAppHash) public onlyAdmin {
  appHash = nextAppHash;
  locked = false;
}