๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๋ถ์ฐํ ๋คํธ์ํฌ์์๋ ๋์๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์ด๋ ต์ต๋๋ค. ๊ฑฐ์ ๋ชจ๋ ๋ธ๋ก์ฒด์ธ์์ ์ด๋ฏธ ์ด๋ฌํ ํ์์ด ๋ฐ์ํ์ต๋๋ค. ์ค์ ๋ก ์ฌ์ฉ์ ๊ฐ์ ์ ๋ขฐ๊ฐ ์๋ ๋คํธ์ํฌ์์๋ ๋ถ์ธํ ์ ์๋ ๋์๋ฅผ ์์ฑํ๋ฉด ๋ง์ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋ฉ๋๋ค.
์ด ๊ธฐ์ฌ์์๋ ๊ฒ์์ ์๋ก ๋ค์ด ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ๋์ง ์ค๋ช
ํฉ๋๋ค. ๊ทธ ์ค ์ฒซ ๋ฒ์งธ๋
์ฒ์์๋ ๋ธ๋ก์ฒด์ธ์ ์ ๋ณด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ซ์๋ฅผ ์์ฑํ ๊ณํ์ด์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ซ์๊ฐ ์กฐ์๋ ์ ์๋ค๋ ๊ฒ์ด ๋ถ๋ช
ํด์ก์ต๋๋ค. ์ด๋ ์๋ฃจ์
์ด ์ ํฉํ์ง ์์์ ์๋ฏธํฉ๋๋ค.
์ฐ๋ฆฌ๋ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์๊ฐํด๋์ต๋๋ค. ์ปค๋ฐ ํ์ฅ ๋ฐฉ์์ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค. ์๋ฒ๋ 1๋ถํฐ 5๊น์ง์ ์ซ์๋ฅผ ์ถ์ธกํ๊ณ ์ฌ๊ธฐ์ ์ํธ๋ฅผ ์ถ๊ฐํ ๋ค์ ๋ค์์ ์ฌ์ฉํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ํด์ฑํ์ต๋๋ค.
ํ๋ ์ด์ด๊ฐ ๋ฒ ํ ์ ํ๊ณ ์๋ฒ๋ ์จ๊ฒจ์ง ์ซ์์ "์๊ธ"์ ์ค๋งํธ ๊ณ์ฝ์ผ๋ก ๋ณด๋์ต๋๋ค. ๊ฐ๋จํ ๋งํด์ ๊ทธ๋ ์นด๋๋ฅผ ๊ณต๊ฐํ์ต๋๋ค. ๊ทธ ํ ์๋ฒ๋ ์ซ์๋ฅผ ํ์ธํ๊ณ ์ฌ์ฉ์์ ์นํจ๋ฅผ ๊ฒฐ์ ํ์ต๋๋ค.
์๋ฒ๊ฐ ํ์ธ์ ์ํด ์ซ์๋ "์๊ธ"์ ๋ณด๋ด์ง ์์ผ๋ฉด ์ฌ์ฉ์๊ฐ ์น๋ฆฌํฉ๋๋ค. ์ด ๊ฒฝ์ฐ ๊ฐ ๊ฒ์๋ง๋ค ์ค๋งํธ ๊ณ์ฝ์ ๋ฏธ๋ฆฌ ๋ฐฐํฌํ๊ณ ์ ์ฌ์ ์ธ ์น๋ฆฌ๋ฅผ ํฌํจํด์ผ ํ์ต๋๋ค. ๋ถํธํ๊ณ ์๊ฐ๊ณผ ๋น์ฉ์ด ๋ง์ด ๋๋ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค. ๊ทธ ๋น์์๋ ๋ค๋ฅธ ์์ ํ ํด๊ฒฐ์ฑ ์ด ์์์ต๋๋ค.
์ต๊ทผ Tradisys ํ์ Waves ํ๋กํ ์ฝ์ ๊ธฐ๋ฅ ์ถ๊ฐ๋ฅผ ์ ์ํ์ต๋๋ค. rsaํ์ธ(). ๊ณต๊ฐ ํค์ ๊ฐ์ธ ํค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก RSA ์๋ช ์ ์ ํจ์ฑ์ ํ์ธํฉ๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋์์ต๋๋ค.
์ฐ๋ฆฌ๋ ์ธ ๊ฐ์ง ๊ฒ์์ ๊ฐ๋ฐํ์ต๋๋ค:
Ride on Waves๋ฅผ ์๋ก ๋ค์ด ๋์๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์ค๋งํธ ๊ณ์ฝ์ ์ฐพ์ ์ ์์ต๋๋ค
ํญ์ผ๋ก ์ด๋ ์คํฌ๋ฆฝํธ ๊ทธ๋ฆฌ๊ณ ์ ํ ๋์ปดํ์ผ๋จ. ์ค๋งํธ ๊ณ์ฝ ์ฝ๋(์ผ๋ช ์คํฌ๋ฆฝํธ)๊ฐ ํ์๋ฉ๋๋ค.
์ค๋งํธ ๊ณ์ฝ ์ฝ๋์๋ ์ผ๋ จ์ ๊ธฐ๋ฅ์ด ํฌํจ๋์ด ์์ต๋๋ค. @Callable๋ก ํ์๋ ํญ๋ชฉ์ ๋ค์์ ์ฌ์ฉํ์ฌ ์์ํ ์ ์์ต๋๋ค. ํธ์ถ ํธ๋์ญ์
. ์ฐ๋ฆฌ๋ ๋ ๊ฐ์ง ๊ธฐ๋ฅ์ ๊ด์ฌ์ด ์์ต๋๋ค. ๋ฒ ํ
ะธ ์ฒ ์:
- ์ฌ๋ฏธ์๋ ๋ฒ ํ (playerChoice)
- func ์ฒ ํ(gameId,rsaSign)
1. ์ฌ์ฉ์๋ ์ธ๊ทธ๋จผํธ ๊ธธ์ด์ ๋ฒ ํ ํฌ๊ธฐ๋ฅผ ์ ํํฉ๋๋ค.
2. ํด๋ผ์ด์ธํธ๋ ๋ฒ ํ
๊ธฐ๋ฅ์ ์์ฑํฉ๋๋ค. ์์ ์ด๋ฏธ์ง์ ๊ฒฝ์ฐ ๋ด๊ธฐ("50").
3. ํด๋ผ์ด์ธํธ๋ Invocation ํธ๋์ญ์ ์ ์ค๋งํธ ๊ณ์ฝ ์ฃผ์(Broadcast InvocationTx)๋ก ๋ณด๋ ๋๋ค. ๊ฑฐ๋์๋ ํตํ ๋งค๊ฐ๋ณ์๋ก ๋ฒ ํ ๊ธฐ๋ฅ์ด ํฌํจ๋์ด ์์ต๋๋ค. ์ด๋ ํธ์ถ ํธ๋์ญ์ ์ด ์ค๋งํธ ๊ณ์ฝ์์ ๋ฒ ํ ๊ธฐ๋ฅ(์ ํ: ๋ฌธ์์ด)์ ์คํ์ ํธ๋ฆฌ๊ฑฐํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
4. ๋ฒ ํ
๊ธฐ๋ฅ์ ๊ณ ๋ คํด๋ณด์ธ์:
@Callable(i)
func bet (playerChoice) = {
let newGameNum = IncrementGameNum()
let gameId = toBase58String(i.transactionId)
let pmt = extract(i.payment)
let betNotInWaves = isDefined(pmt.assetId)
let feeNotInWaves = isDefined(pmt.assetId)
let winAmt = ValidateBetAndDefineWinAmt(pmt.amount, playerChoice)
let txIdUsed = isDefined(getString(this, gameId))
if (betNotInWaves)
then throw ("Bet amount must be in Waves")
else if (feeNotInWaves)
then throw ("Transaction's fee must be in Waves")
else if (txIdUsed)
then throw ("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)
- ๊ฒ์ ์ํ = ์ ์ถ๋จ
- ํ๋ ์ด์ด์ ์ ํ(์ธ๊ทธ๋จผํธ ๊ธธ์ด 50)
- ๊ณต๊ฐํค
- ์ ์ฌ์ ์น๋ฆฌ(ํ๋ ์ด์ด์ ๋ฒ ํ ์ ๋ฐ๋ผ ๋ค๋ฆ)
๋ธ๋ก์ฒด์ธ์ ๋ฐ์ดํฐ ๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค(ํค-๊ฐ).
{
"type": "string",
"value": "03WON_0283_448t8Jn9P3717UnXFEVD5VWjfeGE5gBNeWg58H2aJeQEgJ_06574069_09116020000_0229",
"key": "2GKTX6NLTgUrE4iy9HtpSSHpZ3G8W4cMfdjyvvnc21dx"
}
"์ด์ "(์ด์ ) โ ๊ฒ์ ์์ด๋ ์๋ก์ด ๊ฒ์. ๋๋จธ์ง ๋ฐ์ดํฐ๋ "๊ฐ" ํ๋ ์ค์ ํฌํจ๋ฉ๋๋ค. ์ด ํญ๋ชฉ์ ํญ์ ์ ์ฅ๋ฉ๋๋ค Data ์ค๋งํธ ๊ณ์ฝ:
5. ์๋ฒ๋ ์ค๋งํธ ๊ณ์ฝ์ "๋ณด๊ณ " ๋ธ๋ก์ฒด์ธ Api๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ก๋ ํธ๋์ญ์
(์ ๊ฒ์)์ ์ฐพ์ต๋๋ค. ์ ๊ฒ์์ ๊ฒ์ ID๋ ์ด๋ฏธ ๋ธ๋ก์ฒด์ธ์ ๊ธฐ๋ก๋์ด ์์ผ๋ฏ๋ก ๋ ์ด์ ๋ณ๊ฒฝํ๊ฑฐ๋ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค.
6. ์๋ฒ๋ ์ฒ ํ ๊ธฐ๋ฅ(gameId, rsaSign)์ ์์ฑํฉ๋๋ค. ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
withdraw ("FwsuaaShC6DMWdSWQ5osGWtYkVbTEZrsnxqDbVx5oUpq", "base64:Gy69dKdmXUEsAmUrpoWxDLTQOGj5/qO8COA+QjyPVYTAjxXYvEESJbSiCSBRRCOAliqCWwaS161nWqoTL/TltiIvw3nKyd4RJIBNSIgEWGM1tEtNwwnRwSVHs7ToNfZ2Dvk/GgPUqLFDSjnRQpTHdHUPj9mQ8erWw0r6cJXrzfcagKg3yY/0wJ6AyIrflR35mUCK4cO7KumdvC9Mx0hr/ojlHhN732nuG8ps4CUlRw3CkNjNIajBUlyKQwpBKmmiy3yJa/QM5PLxqdppmfFS9y0sxgSlfLOgZ51xRDYuS8NViOA7c1JssH48ZtDbBT5yqzRJXs3RnmZcMDr/q0x6Bg==")
7. ์๋ฒ๋ Invocation ํธ๋์ญ์ ์ ์ค๋งํธ ๊ณ์ฝ์ผ๋ก ๋ณด๋ ๋๋ค(InvocationTx ๋ธ๋ก๋์บ์คํธ). ํธ๋์ญ์ ์๋ ํ์ฑ๋ ์ฒ ํ ํจ์(gameId, rsaSign)์ ๋ํ ํธ์ถ์ด ํฌํจ๋์ด ์์ต๋๋ค.
ํจ์์๋ ๋ค์์ด ํฌํจ๋ฉ๋๋ค. ๊ฒ์ ์์ด๋ ์๋ก์ด ๊ฒ์๊ณผ ๊ฐ์ธ ํค๋ฅผ ์ฌ์ฉํ์ฌ ๊ณ ์ ์๋ณ์๋ฅผ RSA ์๋ช
ํ ๊ฒฐ๊ณผ์
๋๋ค. ์๋ช
๊ฒฐ๊ณผ๋ ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค.
์ด๊ฒ์ ๋ฌด์์ ์๋ฏธํ ๊น์?
๋์ผํ ๊ฐ(๊ฒ์ ID)์ ๊ฐ์ ธ์ RSA ์๋ช ๋ฐฉ๋ฒ์ ์ ์ฉํฉ๋๋ค. ์ฐ๋ฆฌ๋ ํญ์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ด RSA ์๊ณ ๋ฆฌ์ฆ์ด ์๋ํ๋ ๋ฐฉ์์ ๋๋ค. ๊ฒ์ ID์ RSA ์ ์ฉ ๊ฒฐ๊ณผ๋ฅผ ์ ์ ์์ผ๋ฏ๋ก ์ต์ข ์ซ์๋ ์กฐ์ํ ์ ์์ต๋๋ค. ์ซ์๋ฅผ ์ ํํ๋ ๊ฒ๋ ์๋ฏธ๊ฐ ์์ต๋๋ค.
8. ๋ธ๋ก์ฒด์ธ์ด ๊ฑฐ๋๋ฅผ ์๋ฝํฉ๋๋ค. ์ฒ ํ ๊ธฐ๋ฅ(gameId, rsaSign)์ ์คํํฉ๋๋ค.
9. ์ถ๊ธ ๊ธฐ๋ฅ ๋ด์์ ์ถ๊ธ์ด ๋ฐ์ํฉ๋๋ค. ์์ฑRandInt ํจ์ (gameId, rsaSign). ์ด๊ฒ์ ๋์ ์์ฑ๊ธฐ์ ๋๋ค.
# @return 1 ... 100
func GenerateRandInt (gameId,rsaSign) = {
# verify RSA signature to proof random
let rsaSigValid = 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)
}
else throw ("Invalid RSA signature")
}
๋๋ - ๊ทธ๋ฆฌ๊ณ ์์์ ์ซ์๊ฐ ์์ต๋๋ค.
๋จผ์ RSA ์๋ช ์ ๊ฒฐ๊ณผ์ธ ๋ฌธ์์ด์ ๊ฐ์ ธ์ต๋๋ค. ๊ฒ์ ์์ด๋ ๊ฐ์ธ ํค(rsaSign). ๊ทธ๋ฐ ๋ค์ SHA-256(sha256(rsaSign)).
์ฐ๋ฆฌ๋ ์๋ช
๊ณผ ํ์ ํด์ฑ์ ๊ฒฐ๊ณผ๋ฅผ ์์ธกํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ๋์ ์์ฑ์ ์ํฅ์ ๋ฏธ์น๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํฉ๋๋ค. ํน์ ๋ฒ์(์: 1์์ 100)์ ์ซ์๋ฅผ ์ป์ผ๋ ค๋ฉด toInt ๋ณํ ํจ์์ %100(
๊ธฐ์ฌ ์์ ๋ถ๋ถ์์ ์ฐ๋ฆฌ๋ ๊ธฐ๋ฅ์ ์ธ๊ธํ์ต๋๋ค. rsaํ์ธ(), ๊ณต๊ฐ ํค์ ๊ฐ์ธ ํค๋ฅผ ์ฌ์ฉํ์ฌ RSA ์๋ช ์ ์ ํจ์ฑ์ ํ์ธํ ์ ์์ต๋๋ค. ๋ค์์ generateRandInt(gameId,rsaSign) ๋ถ๋ถ์ ๋๋ค:
rsaVerify (SHA256, toBytes(gameId), rsaSign, RSAPUBLIC)
๊ณต๊ฐ ํค RSAPUBLIC ๋ฐ rsaSign ๋ฌธ์์ด์ด ์ ๋ ฅ์ ์ ๋ฌ๋ฉ๋๋ค. ์๋ช ์ ์ ํจ์ฑ์ด ๊ฒ์ฌ๋ฉ๋๋ค. ํ์ธ์ด ์ฑ๊ณตํ๋ฉด ๋ฒํธ๊ฐ ์์ฑ๋ฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์์คํ ์ ์๋ช ์ด ์ ํจํ์ง ์์ ๊ฒ์ผ๋ก ๊ฐ์ฃผํฉ๋๋ค(์๋ชป๋ RSA ์๋ช ).
์๋ฒ๋ ๊ฐ์ธ ํค๋ก ๊ฒ์ ID์ ์๋ช ํ๊ณ 2880 ๋ธ๋ก ์ด๋ด์ ์ ํจํ Rsa ์๋ช ์ ๋ณด๋ด์ผ ํฉ๋๋ค. ๋งค๊ฐ๋ณ์๋ ์ค๋งํธ ๊ณ์ฝ์ ๋ฐฐํฌํ ๋ ๊ตฌ์ฑ๋ฉ๋๋ค. ํ ๋น๋ ์๊ฐ ๋ด์ ์๋ฌด ์ผ๋ ์ผ์ด๋์ง ์์ผ๋ฉด ์ฌ์ฉ์๊ฐ ์น๋ฆฌํฉ๋๋ค. ์ด ๊ฒฝ์ฐ, ๊ฒฝํ์ ๋ฐ๋์ ๊ทํ์ ์ฃผ์๋ก ์ง์ ๋ฐ์ก๋์ด์ผ ํฉ๋๋ค. ์ด๋ ์์ค๋ก ์ด์ด์ง๊ธฐ ๋๋ฌธ์ "์๋ฒ๊ฐ ๋ถ์ ํ์๋ฅผ ํ๋ ๊ฒ์ ์์ต์ฑ์ด ์๋ค"๋ ๊ฒ์ด ๋ฐํ์ก์ต๋๋ค. ์๋๋ ์์์ ๋๋ค.
์ฌ์ฉ์๊ฐ ํ๋ ์ด ์ค์
๋๋ค.
๊ฒ์์์ ์ซ์๋ฅผ ์์ฑํ๊ธฐ ์ํด ์ฐ๋ฆฌ๋ ๋ธ๋ก์ฒด์ธ์ด ์๋ ์ธ๋ถ ์์คํ ์ธ ์ค๋ผํด์ ์ฌ์ฉํฉ๋๋ค. ์๋ฒ๋ ๊ฒ์ ID์ RSA ์๋ช ์ ์ํํฉ๋๋ค. ์ค๋งํธ ๊ณ์ฝ์ ์๋ช ์ ์ ํจ์ฑ์ ํ์ธํ๊ณ ์น์๋ฅผ ๊ฒฐ์ ํฉ๋๋ค. ์๋ฒ๊ฐ ์๋ฌด๊ฒ๋ ๋ณด๋ด์ง ์์ผ๋ฉด ์ฌ์ฉ์๊ฐ ์๋์ผ๋ก ์น๋ฆฌํฉ๋๋ค.
๊ธฐ์ ์ ์ผ๋ก ์กฐ์์ด ๋ถ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ์ด๋ ์ ์งํ ์์ฑ ๋ฐฉ๋ฒ์
๋๋ค. ๋ชจ๋ Tradisys ๊ฒ์์ ์ค๋ช
๋ ์๊ณ ๋ฆฌ์ฆ์ ๊ธฐ๋ฐ์ผ๋ก ์๋ํฉ๋๋ค. ์ด๊ฒ์ด ๋ธ๋ก์ฒด์ธ ๊ฒ์์ด ์๋ํ๋ ๋ฐฉ์์
๋๋ค. ๋ชจ๋ ๊ฒ์ด ํฌ๋ช
ํ๊ณ ๊ฒ์ฆ ๊ฐ๋ฅํฉ๋๋ค. ๋ค๋ฅธ ๋ธ๋ก์ฒด์ธ์๋ ์ด๋ฌํ ์์คํ
๊ณผ ์ ์ฌํ ์์คํ
์ด ์์ต๋๋ค. ์ด๊ฒ์ ์๋นํ ๋ฌด์์์
๋๋ค.
์ถ์ฒ : habr.com