这是分布式网络中随机数生成的解决方案。
在开发我们的游戏过程中,我们需要解决一个问题,在分布式网络中生成随机数很复杂,现几乎所有区块链都面临这个问题。因此,在任何人都无法相互信任的互联网之间,创建随机数可以解决许多问题。
在本文中,我们将讲解我们是如何在我们的游戏中解决这个问题的。首当其冲的便是Waves XmasTree.
起初,我们计划使用区块链信息来生成一个数字,但在进一步的研究中我们发现创建这个数字的过程可以被操纵干预,因此我们不得不放弃这个方案。
此后我们提出了一个新的方案, 使用“Commit-Reveal”方案。首先服务器生成一个1到5之间的数字,然后往其中添加“盐”并且使用Keccak function 进行哈希值处理。服务器使用已储存的数字对智能合约进行预调试,结论是游戏被有效的简化,为用户猜测哈希值下所隐藏的数字。
玩家下注后服务器将发送一个隐藏的数字并且将其“盐”带到一个智能合约中。换句话说,信息已被揭露,之后服务器也会验证这个数字并判断用户的输赢。
如果服务器未发送该数字和“盐”进行验证,则该用户赢了。在这种情况下,必须提前部署智能合约,并为每场比赛安排潜在的获胜机会。这是非常不方便,成本高且消耗大量时间。但那时还没有提出其它安全的解决方案。
此后不久,Tradisys团队提议向Waves协议添加rsaVerify()函数。这将根据公钥和私钥检查RSA签名的有效性。根据我们的建议,该功能已被添加。
我们开发了三款新游戏:《摇骰子》,《掷硬币》和《乘浪行》。在每个游戏中,每款游戏都部署了新的随机数方法,让我们仔细观察它是如何工作的。
让我们先看看生成的随机数,你可以在此处查看智能合约。
切换到脚本选项卡并选择反编译,您即可看到智能合约的代码(或脚本)。
智能合约的代码由一系列的函数组成。其中的@Callable 可以通过调用事务选项运行。我们对其中两个很感兴趣:下注和撤回:
1. 用户选择范围和下注大小
2. 客户安排下注功能。对于上面的图像,即为bet(«50»)
3. 客户端将调用事务发送到智能合约地址(播报InvocationTx)。作为Call参数的交易依据并包含bet函数。这意味着调用事务开始在智能合约上执行下注函数(选择:字符串)。
4. 让我们看一看bet函数
@Callable(i)
func bet (playerChoice) = {
letnewGameNum = IncrementGameNum()
letgameId = toBase58String(i.transactionId)
let pmt =extract(i.payment)
letbetNotInWaves = isDefined(pmt.assetId)
letfeeNotInWaves = isDefined(pmt.assetId)
letwinAmt = ValidateBetAndDefineWinAmt(pmt.amount, playerChoice)
lettxIdUsed = isDefined(getString(this, gameId))
if(betNotInWaves)
thenthrow ("Bet amount must be in Waves")
else if(feeNotInWaves)
thenthrow ("Transaction's fee must be in Waves")
elseif (txIdUsed)
thenthrow ("Passed txId had been used before. Game aborted.")
else{
let playerPubKey58 = toBase58String(i.callerPublicKey)
let gameDataStr = FormatGameDataStr(STATESUBMITTED, playerChoice,playerPubKey58, height, winAmt, "")
ScriptResult(WriteSet(cons(DataEntry(RESERVATIONKEY,ValidateAndIncreaseReservedAmt(winAmt)),cons(DataEntry(GAMESCOUNTERKEY,newGameNum), cons(DataEntry(gameId, gameDataStr), nil)))), TransferSet(cons(ScriptTransfer(SERVER,COMMISSION, unit), nil)))
}
该函数在智能合约中记录了一场新的游戏。
游戏的ID = game id
游戏状态 = 已提交
玩家选择(选择范围为50)
公钥
潜在奖励(取决于玩家的下注)
这是键值数据库在区块链上的呈现方式
{
"type": "string",
"value":"03WON_0283_448t8Jn9P3717UnXFEVD5VWjfeGE5gBNeWg58H2aJeQEgJ_06574069_09116020000_0229",
"key":"2GKTX6NLTgUrE4iy9HtpSSHpZ3G8W4cMfdjyvvnc21dx" }
“Key”是新游戏的game id,其他数据都包括在了value属性部分。
这是数据都储存在智能合约的数据一栏中。
5. 服务器通过区块链API接口发送新的事务(新的游戏),游戏ID已被区块链记录,因此不可能去删除或者篡改该数据。
6. 服务器生成撤回函数(gameId,rsaSign)例如:
7. 服务器发送一个调用事务到智能合约中(broadcastInvocationTX)。该事务包含了一个调用以生成撤回函数。(gameId, rasSign):
该函数是含有 game id 以及RSA签名的唯一id,因此签名保证了其不可篡改性。
这意味着什么?
我们使用相同的值并且将RSA签名应用在其中,这就是RSA算法的工作原理。由于game id和RSA算法的结果是未知的,因此不可能操控其最终数值,并且猜测最终数值也变得毫无意义。
8. 区块链接收到一个运行撤回函数的事务(gameId,rsaSign)
9. 撤回函数内包含一个调用GenerateRandIn函数。
# @return 1 ... 100
func GenerateRandInt (gameId,rsaSign) = {
#verify RSA signature to proof random
letrsaSigValid = rsaVerify (SHA256, toBytes(gameId), rsaSign, RSAPUBLIC)
if(rsaSigValid)
then{
let rand = (toInt(sha256(rsaSign)) % 100)
if ((0 > rand))
then ((-1 * rand) + 1)
else (rand + 1)
}
elsethrow ("Invalid RSA signature")
rand 即为一个随机数
首先,RSA签名结果的字符串已被使用。其次,其已通过SHA-256哈希处理。
我们无法预测签名结果以及后续的哈希处理,因此生成结果不可能被干预。为了获取指定范围内的一个数字(例如从1到100),转换函数toInt 以及%100(mod 模拟)也被应用在其中。
在本文开头,我们提到了rsaVerify()函数,该函数允许通过私钥针对公钥来检查RSA签名的有效性。这里是部分GenerateRandInt(gameId,rsaSign):
rsaVerify(SHA256, toBytes(gameId), rsaSign, RSAPUBLIC)
以此开始, RSAPUBLIC公钥以及rsaSign字符串已被使用,该签名用以验证其有效性。如果验证通过,那么数字将会生成。否则系统将会判定该签名无效(Invalid RSA signature)
服务器需要使用私钥注册游戏ID并且在2880个区块内发送有效的RSA签名。在部署智能合约的同时该选项已被管理。如果规定时间内没有其他情况则玩家获胜。在此基础上,奖励会被用户单独发送。 就此而言,作弊对服务器将毫无益处,因为作弊会导致输局。如下示例:
玩家参与摇色子游戏。玩家从6个面中选择2个,并下注14个WAVES。如果服务器未在设定的时间(2,880区块)内向智能合约发送有效的RSA签名,则用户将收到34.44 WAVES。
就数字生成而言,我们使用了预言机,一个非区块链的外部系统。服务器应用一个RSA签名到游戏ID中,智能合约将会检查签名的有效性并且判断赢家。如果服务器未发送结果,那么玩家则会自动胜出。
这种方法保证了人为操纵是不可能的,所有Tradisys游戏都基于以上阐述的算法以保证我们游戏的公平性和透明性。所有内容都可以公开审核以确保其公正。
关于 WAVES
Waves(波币)是始于2016年的技术派公链劲旅,Neutrino协议,Gravity协议和Waves Enterprise是Waves品牌旗下三驾马车,覆盖了DeFi,跨链与企业应用等热门领域。
Waves是一个面向Web3.0应用及分布解决方案的开放区块链协议和开发者工具集。Waves的愿景是通过提升IT系统的安全性,可靠性和速度,来支持开发者建立自己的链上应用,促进区块链产业的大规模落地。
官网:https://waves.tech/
白皮书:https://docs.waves.tech/en/
QQ:664112321
公众号:Waves中文社区
微博:Waves中文社区
WAVES微信群
『声明:本内容仅供广大加密爱好者科普学习和交流,不构成投资建议,请理性看待,提高风险意识。文章版权和最终解释权归Waves中文社区所有。我们尊重版权,如有疑问请第一时间联系我们,非常感谢。』