Created
July 21, 2019 12:36
-
-
Save IgorShadurin/e6aac15618128b21643117831b56a0d4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# STDLIB_VERSION 3 #-} | |
{-# CONTENT_TYPE DAPP #-} | |
{-# SCRIPT_TYPE ACCOUNT #-} | |
let ServerPublicKey = base58'kYxoGdY4mv5zMYWYJTq3Pp3uLDuLphTYfT8epjYEJvy' | |
let ServerAddress = addressFromStringValue("3MuJmCSEUgBNy1R2gesk59xDbWcuTKwwixW") | |
let RouletteSections = 21 | |
let DataGameNumberKey = "APP_GAME_ID" | |
let DataUserGameKey = "USER_GAME_ID_" | |
let DataAmountKey = "AMOUNT" | |
let DataSectionKey = "SECTION" | |
let DataStatusKey = "STATUS" | |
let DataResultKey = "RESULT" | |
let DataWinAmountKey = "WIN_AMOUNT" | |
let DataStatusNew = "NEW" | |
let DataStatusWin = "WIN" | |
let DataStatusLoose = "LOOSE" | |
let WAVELET = ((100 * 1000) * 1000) | |
let COMMISSION = ((5 * WAVELET) / 1000) | |
let BET1 = (1 * WAVELET) | |
let BET2 = (2 * WAVELET) | |
let BET4 = (4 * WAVELET) | |
let BET8 = (8 * WAVELET) | |
let BET14 = (14 * WAVELET) | |
let Sections = [0,2,20,2,5,2,10,2,6,2,5,2,6,2,5,2,10,2,5,2,6] | |
let ErrorOnlyWavesAccepted = "Only waves accepted" | |
let ErrorMustGreaterThan0 = "Parameter size must be greater than 0" | |
let ErrorMustLessThan100 = "Parameter size must be less than 100" | |
let ErrorBetMustBeInWaves = "Bet amount must be in Waves" | |
let ErrorTransactionMustBeInWaves = "Transaction's fee must be in Waves" | |
let ErrorTransactionUsed = "Passed txId had been used before. Game aborted." | |
let ErrorKeyNotFound = "Key not found: " | |
let ErrorGameOver = "Game already is over " | |
let ErrorIncorrectSectionResult = "Incorrect section result" | |
let ErrorBetAmountNotInRange = "Bet amount is not in range" | |
func StoreData(transactionId: String, key: String, value: String)={ | |
DataEntry(transactionId + "_" + key, value) | |
} | |
func StoreDataInt(transactionId: String, key: String, value: Int)={ | |
DataEntry(transactionId + "_" + key, value) | |
} | |
func GetData(key: String) = { | |
match getString(this, key) { | |
case str: String => str | |
case _ => throw(ErrorKeyNotFound + key) | |
} | |
} | |
func GetDataString(transactionId: String, key: String) = { | |
let fullKey = transactionId + "_" + key | |
match getString(this, fullKey) { | |
case str: String => str | |
case _ => throw(ErrorKeyNotFound + fullKey) | |
} | |
} | |
func GetDataInt(transactionId: String, key: String) = { | |
let fullKey = transactionId + "_" + key | |
match getInteger(this, fullKey) { | |
case str: Int => str | |
case _ => throw(ErrorKeyNotFound + fullKey) | |
} | |
} | |
func NewGameId () = { | |
let gameNum = match getInteger(this, DataGameNumberKey) { | |
case num: Int => num | |
case _ => 0 | |
} | |
(gameNum + 1) | |
} | |
func GenerateRandInt (gameId: String, rsaSign: String) = { | |
let rsaSigValid = sigVerify(fromBase58String(gameId), fromBase58String(rsaSign), ServerPublicKey); | |
if (rsaSigValid) then | |
{ | |
let rand = (toInt(sha256(toBytes(rsaSign))) % RouletteSections) | |
if ((0 > rand)) | |
then (-1 * rand) | |
else rand | |
} | |
else throw("Invalid RSA signature") | |
} | |
func GetStatus(result: Boolean) = { | |
if(result) then DataStatusWin | |
else DataStatusLoose | |
} | |
func GetWinAmount (betAmt: Int, section: Int) = { | |
#let isIncorrectResult = section <= 0 || section > 20 | |
let isCorrectResult = if (if (if (if ((section == 2)) | |
then true | |
else (section == 5)) | |
then true | |
else (section == 6)) | |
then true | |
else (section == 10)) | |
then true | |
else (section == 20) | |
let betAmtValid = if (if (if (if ((betAmt == (BET1 + COMMISSION))) | |
then true | |
else (betAmt == (BET2 + COMMISSION))) | |
then true | |
else (betAmt == (BET4 + COMMISSION))) | |
then true | |
else (betAmt == (BET8 + COMMISSION))) | |
then true | |
else (betAmt == (BET14 + COMMISSION)) | |
if (!isCorrectResult) then throw(ErrorIncorrectSectionResult) | |
else if(betAmtValid) then (betAmt - COMMISSION) * section | |
else throw(ErrorBetAmountNotInRange) | |
} | |
@Callable(i) | |
func bet(expectedResult: Int) = { | |
let gameNumber = NewGameId() | |
let gameTransactionId = toBase58String(i.transactionId) | |
let address = toBase58String(i.caller.bytes) | |
let pmt = extract(i.payment) | |
let txIdUsed = isDefined(getString(this, gameTransactionId)) | |
let betNotInWaves = isDefined(pmt.assetId) | |
let feeNotInWaves = isDefined(pmt.assetId) | |
let amount = pmt.amount; | |
let winAmt = GetWinAmount(pmt.amount, expectedResult) | |
if (betNotInWaves) then throw(ErrorBetMustBeInWaves) | |
else if (feeNotInWaves) then throw(ErrorTransactionMustBeInWaves) | |
else if (txIdUsed) then throw(ErrorTransactionUsed) | |
else { | |
ScriptResult( | |
WriteSet([ | |
DataEntry(DataUserGameKey + toString(gameNumber), gameTransactionId), | |
DataEntry(gameTransactionId, address), | |
DataEntry(DataGameNumberKey, gameNumber), | |
StoreDataInt(gameTransactionId, DataAmountKey, amount), | |
StoreDataInt(gameTransactionId, DataSectionKey, expectedResult), | |
StoreData(gameTransactionId, DataStatusKey, DataStatusNew), | |
StoreDataInt(gameTransactionId, DataWinAmountKey, winAmt) | |
]), | |
TransferSet([ | |
ScriptTransfer(ServerAddress, COMMISSION, unit) | |
]) | |
) | |
} | |
} | |
@Callable(i) | |
func result(gameTransactionId: String, rsa: String) = { | |
let randIndex = GenerateRandInt(gameTransactionId, rsa) | |
let selectedSection = GetDataInt(gameTransactionId, DataSectionKey) | |
let status = GetDataString(gameTransactionId, DataStatusKey) | |
if (status == DataStatusNew) then { | |
let randSection = Sections[randIndex] | |
let isWin = randSection == selectedSection | |
let writeSet = WriteSet([ | |
StoreData(gameTransactionId, DataStatusKey, GetStatus(isWin)), | |
StoreDataInt(gameTransactionId, DataResultKey, randSection) | |
]) | |
if(isWin) then { | |
let wallet = GetData(gameTransactionId) | |
let winAmount = GetDataInt(gameTransactionId, DataWinAmountKey) | |
ScriptResult( | |
writeSet, | |
TransferSet([ | |
ScriptTransfer(addressFromStringValue(wallet), winAmount, unit) | |
]) | |
) | |
} else { | |
writeSet | |
} | |
} else throw(ErrorGameOver + status) | |
} | |
@Verifier(tx) | |
func verify() = if (sigVerify(tx.bodyBytes, getElement(tx.proofs, 0), tx.senderPublicKey)) | |
then match tx { | |
#case ttx: TransferTransaction => ((wavesBalance(this) - ttx.amount) >= 0) | |
case ttx: TransferTransaction => true | |
case stx: SetScriptTransaction => true | |
case _ => false | |
} | |
else false |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment