Waves ์Šค๋งˆํŠธ ์ž์‚ฐ: ํ‘๋ฐฑ ๋ชฉ๋ก, ๊ฐ„๊ฒฉ ๊ฑฐ๋ž˜

Waves ์Šค๋งˆํŠธ ์ž์‚ฐ: ํ‘๋ฐฑ ๋ชฉ๋ก, ๊ฐ„๊ฒฉ ๊ฑฐ๋ž˜

์ด์ „ ๋‘ ๊ธฐ์‚ฌ์—์„œ๋Š” ์Šค๋งˆํŠธ ๊ณ„์ •๊ณผ ์Šค๋งˆํŠธ ๊ณ„์ • ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฝ๋งค ๊ฐœ์ตœ ๋ฐ ๋กœ์—ดํ‹ฐ ํ”„๋กœ๊ทธ๋žจ ์ƒ์„ฑ๊ทธ๋ฆฌ๊ณ  ๋„์›€๋„ ์ค˜ ๊ธˆ์œต์ƒํ’ˆ์˜ ํˆฌ๋ช…์„ฑ ํ™•๋ณด.

์ด์ œ ์Šค๋งˆํŠธ ์ž์‚ฐ๊ณผ ์ž์‚ฐ ๋™๊ฒฐ, ์ง€์ •๋œ ์ฃผ์†Œ์—์„œ์˜ ๊ฑฐ๋ž˜ ์ œํ•œ ๋“ฑ ์Šค๋งˆํŠธ ์ž์‚ฐ์˜ ์—ฌ๋Ÿฌ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Waves ์Šค๋งˆํŠธ ์ž์‚ฐ์„ ์‚ฌ์šฉํ•˜๋ฉด ์Šค๋งˆํŠธ ๊ณ„์ •๊ณผ ๋™์ผํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ๋”ฐ๋ผ ์ž์‚ฐ์— ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์˜ค๋ฒ„๋ ˆ์ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šค๋งˆํŠธ ์ž์‚ฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ๋œ ๊ฐ๊ฐ์˜ ์ƒˆ๋กœ์šด ๊ฑฐ๋ž˜๋Š” ๋จผ์ € ์Šคํฌ๋ฆฝํŠธ์— ์˜ํ•ด ํ™•์ธ๋˜๊ณ  ๊ทธ ๋‹ค์Œ์—๋Š” ๋ธ”๋ก์ฒด์ธ์— ์˜ํ•ด ํ™•์ธ๋ฉ๋‹ˆ๋‹ค.

์Šค๋งˆํŠธ ์ž์‚ฐ๊ณผ ์Šค๋งˆํŠธ ๊ณ„์ •์˜ ๋‹ค์Œ ์ฐจ์ด์ ์— ์ฃผ๋ชฉํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์Šค๋งˆํŠธ ์ž์‚ฐ์˜ ์ฝ”๋“œ์—์„œ๋Š” ์ฆ๋ช…์„ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๊ธฐ์‚ฌ์—์„œ).
  2. ์Šค๋งˆํŠธ ๊ณ„์ • ์ฝ”๋“œ์—์„œ๋Š” ํ•ด๋‹น ๊ณ„์ •์ด ์ผ์น˜์ž ๊ณ„์ •์ธ ๊ฒฝ์šฐ์—๋งŒ ExchangeTransaction์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ˆœ์„œ๋งŒ ํ™•์ธ๋ฉ๋‹ˆ๋‹ค. ์Šค๋งˆํŠธ ์ž์‚ฐ ์ฝ”๋“œ์—์„œ๋Š” ์ฃผ๋ฌธ์„ ์ง์ ‘ ํ™•์ธํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ExchangeTransaction์„ ํ™•์ธํ•˜๊ณ  ํ•„์š”ํ•œ ๊ฒฝ์šฐ ํ•ด๋‹น ์ฃผ๋ฌธ์„ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. ์Šค๋งˆํŠธ ๊ณ„์ •๊ณผ ๋‹ฌ๋ฆฌ ์Šค๋งˆํŠธ ์ž์‚ฐ์—๋Š” ์ƒํƒœ๊ฐ€ ์—†์ง€๋งŒ ์Šคํฌ๋ฆฝํŠธ์—์„œ ๊ณ„์ • ์ƒํƒœ์— ๊ณ„์† ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šค๋งˆํŠธ ์ž์‚ฐ์€ ๊ณ„์•ฝ์„œ ์ž‘์„ฑ์„ ํฌ๊ฒŒ ๋‹จ์ˆœํ™”ํ•˜์—ฌ ๋งŽ์€ ์‚ฌ๋ก€์˜ ๊ตฌํ˜„์„ ๊ฐ„๊ฒฐํ•˜๊ณ  ์šฐ์•„ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ž์‚ฐ ๋™๊ฒฐ

์ž์‚ฐ์„ ํŠน์ • ๋ธ”๋ก ๋†’์ด๋กœ ๊ณ ์ •ํ•˜๋ ค๋ฉด ๋ชฉํ‘œ ๋†’์ด, ๋‹ค์Œ ์Šค๋งˆํŠธ ์ž์‚ฐ์˜ ์Šคํฌ๋ฆฝํŠธ์—์„œ ์ด ๊ฐ’์„ ๊ฐ„๋‹จํžˆ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let targetHeight = 1500000
height >= targetHeight
 
height - ั„ัƒะฝะบั†ะธั ัะทั‹ะบะฐ, ะฒะพะทั€ะฐั‰ะฐัŽั‰ะฐั ั‚ะตะบัƒั‰ัƒัŽ ะฒั‹ัะพั‚ัƒ.

์ผ์น˜์ž ํŠน์ • ์กฐ๊ฑด

ํŠน์ • ์ผ์น˜์ž๋ฅผ ์›ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์„ค์ •ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์Šค๋งˆํŠธ ์ž์‚ฐ ์Šคํฌ๋ฆฝํŠธ์—์„œ ํ•ด๋‹น ์ฃผ์†Œ๋ฅผ ๋ณด๋‚ธ ์‚ฌ๋žŒ์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

match tx {
    case t : ExchangeTransaction =>
        t.sender == addressFromString("3PJaDyprvekvPXPuAtxrapacuDJopgJRaU3")
    case _ => true
}

์ˆ˜์‹ ์ž์˜ "ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ"

ํ† ํฐ์ด ํŠน์ • ๊ณ„์ •์—๋งŒ ์ „์†ก๋˜๋„๋ก ํ—ˆ์šฉํ•˜๋ ค๋ฉด(์ˆ˜์‹ ์ž์˜ "ํ™”์ดํŠธ ๋ฆฌ์ŠคํŠธ" ์ƒ์„ฑ) ๋ชฉ๋ก์— ํฌํ•จ๋˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋‹ค์Œ ๊ตฌ์„ฑํ‘œ์™€ ํ•จ๊ป˜ ์Šค๋งˆํŠธ ์ž์‚ฐ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

match tx {
  case t : TransferTransaction =>
    let trustedRecipient1 = addressFromString("3P6ms9EotRX8JwSrebeTXYVnzpsGCrKWLv4")
    let trustedRecipient2 = addressFromString("3PLZcCJyYQnfWfzhKXRA4rteCQC9J1ewf5K")
    let trustedRecipient3 = addressFromString("3PHrS6VNPRtUD8MHkfkmELavL8JnGtSq5sx")
    t.recipient == trustedRecipient1 || t.recipient == trustedRecipient2 || t.recipient == trustedRecipient3
  case _ => false
}

๋ณด์•ˆ์ƒ์˜ ์ด์œ ์™€ ์–ธ์–ด์˜ ์™„์ „์„ฑ ์ž…์ฆ์„ ์œ„ํ•ด ๋ชฉ๋ก์—๋Š” ๋ฐ˜๋ณต๊ธฐ ๊ตฌํ˜„์ด ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Š” ๊ตฌ์ฒด์ ์ธ ์š”์†Œ์˜ ์ง‘ํ•ฉ์œผ๋กœ ์ •์˜๋ฉ๋‹ˆ๋‹ค.

์ˆ˜์‹ ์ž์˜ "๋ธ”๋ž™๋ฆฌ์ŠคํŠธ"

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํŠน์ • ๊ณ„์ •์— ํ† ํฐ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ์„ ๊ธˆ์ง€ํ•˜๋ ค๋ฉด "๋ธ”๋ž™๋ฆฌ์ŠคํŠธ"๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์ •ํ™•ํžˆ ๋™์ผํ•œ ์Šค๋งˆํŠธ ์ž์‚ฐ์ด ์‚ฌ์šฉ๋˜์ง€๋งŒ ์ฃผ์†Œ๊ฐ€ ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ์— ์—†๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ํ™•์ธ๋ฉ๋‹ˆ๋‹ค.

match tx {
  case t : TransferTransaction =>
    let bannedRecipient1 = addressFromString("3P6ms9EotRX8JwSrebeTXYVnzpsGCrKWLv4")
    let bannedRecipient2 = addressFromString("3PLZcCJyYQnfWfzhKXRA4rteCQC9J1ewf5K")
    let bannedRecipient3 = addressFromString("3PHrS6VNPRtUD8MHkfkmELavL8JnGtSq5sx")
    t.recipient != bannedRecipient1 && t.recipient != bannedRecipient2 && t.recipient != bannedRecipient3
  case _ => false
}

๋ฐœํ–‰์ž์˜ ํ—ˆ๊ฐ€๋ฅผ ๋ฐ›์•„ ๋ฐœ์†ก

์Šค๋งˆํŠธ ์ž์‚ฐ์„ ์ด์šฉํ•˜๋ฉด ๋ฐœ๊ธ‰์ž์˜ ํ—ˆ๊ฐ€๊ฐ€ ์žˆ์–ด์•ผ๋งŒ ์Šค๋งˆํŠธ ์ž์‚ฐ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜๋„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์•ฝ์ •/๋ถ€์ฑ„ ๋ผ๋ฒจ). ๋ฐœํ–‰์ž๋Š” ๊ณ„์ • ์ƒํƒœ์— ๊ฑฐ๋ž˜ ID๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ๋™์˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

match tx {
  case t : TransferTransaction =>
    let issuer = extract(addressFromString("3P6ms9EotRX8JwSrebeTXYVnzpsGCrKWLv4"))
    #ัƒะฑะตะถะดะฐะตะผัั, ั‡ั‚ะพ ะฒ ัั‚ะตะนั‚ะต ัะผะธั‚ะตะฝั‚ะฐ ัะพะดะตั€ะถะธั‚ัั ID ั‚ะตะบัƒั‰ะตะน ั‚ั€ะฐะฝะทะฐะบั†ะธะธ
    isDefined(getInteger(issuer, toBase58String(t.id)))
  case _ => false
}

ํŠน์ • ์ฝ”์ธ์œผ๋กœ๋งŒ ๊ตํ™˜

์Šค๋งˆํŠธ ์ž์‚ฐ์€ ํŠน์ • ์ฝ”์ธ์œผ๋กœ๋งŒ ๊ตํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋น„ํŠธ์ฝ”์ธ โ€‹โ€‹๊ตํ™˜๋งŒ ํ—ˆ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let BTCId = base58'8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS'
match tx {
  case t : ExchangeTransaction =>
    t.sellOrder.assetPair.priceAsset == BTCId ||
     t.sellOrder.assetPair.amountAsset == BTCId
  case _ => true
}

์˜ค๋ผํด์˜ ๊ฐ€๊ฒฉ์œผ๋กœ ๊ฑฐ๋ž˜

์Šค๋งˆํŠธ ์ž์‚ฐ ์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์˜ค๋ผํด ์ƒํƒœ์—์„œ ๊ณ ์ •๋œ ๊ฐ€๊ฒฉ์œผ๋กœ๋งŒ ๊ฑฐ๋ž˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ถŒํ•œ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๊ทธ๋Ÿฌํ•œ ์Šคํฌ๋ฆฝํŠธ์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค.

let oracle = Address(base58'3PLNmokt22NrSiNvCLvwMUP84LCMJqbXwAD')
let assetId = toBase58String(base58'oWgJN6YGZFtZrV8BWQ1PGktZikgg7jzGmtm16Ktyvjd')
 
match tx {
  #ะทะฐะฟั€ะตั‰ะฐะตะผ ะฟะตั€ะตะดะฐั‡ัƒ ะฐััะตั‚ะฐ
  case t: TransferTransaction | MassTransferTransaction => false
  case e: ExchangeTransaction =>
    #ัƒะฑะตะถะดะฐะตะผัั, ั‡ั‚ะพ ั‚ะพั€ะณะพะฒะปั ะฟั€ะพะธัั…ะพะดะธั‚ ะฟะพ ั†ะตะฝะต, ะทะฐะดะฐะฝะฝะพะน ะฒ ัั‚ะตะนั‚ะต ะพั€ะฐะบะปะฐ ะดะปั ัั‚ะพะณะพ ะฐััะตั‚ะฐ
    let correctPrice = e.price == extract(getInteger(oracle, assetId))
    #ัƒะฑะตะถะดะฐะตะผัั, ั‡ั‚ะพ ั‚ะพั€ะณะพะฒะปั ะฟั€ะพะธัั…ะพะดะธั‚ ะฒ ะพะฑะผะตะฝ ะฝะฐ WAVES
    let correctPriceAsset = !isDefined(e.sellOrder.assetPair.priceAsset) 
correctPrice && correctPriceAsset
  case _ => true
}

์—ฌ๊ธฐ์„œ ๊ฑฐ๋ž˜๊ฐ€ ์ˆ˜ํ–‰๋˜๋Š” ์ž์‚ฐ์˜ ID๋ฅผ ํ™•์ธํ•  ๋•Œ ๋ช…ํ™•ํ•˜์ง€ ์•Š์€ ์ง€์ ์— ์ง๋ฉดํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์š”์ ์€ ์ž์‚ฐ ID๊ฐ€ ์ •์˜๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ WAVES์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฝํŠธ์—์„œ ์šฐ๋ฆฌ๋Š” ์ •ํ™•ํžˆ ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ WAVES์™€ ํ•จ๊ป˜ ๊ฑฐ๋ž˜๊ฐ€ ์ˆ˜ํ–‰๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๊ณ ์ • ๊ฐ€๊ฒฉ ์ธ์ƒ

์Šค๋งˆํŠธ ์ž์‚ฐ์— ๋Œ€ํ•ด ๊ณ ์ • ๊ฐ€๊ฒฉ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ์ฃผ์–ด์ง„ ๋น„์œจ์— ๋”ฐ๋ผ ๋‹จ๊ณ„์ ์œผ๋กœ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ 5๋ธ”๋ก๋งˆ๋‹ค ๊ฐ€๊ฒฉ์ด 1000%์”ฉ ์ฆ๊ฐ€ํ•˜๋Š” ์ž์‚ฐ ์Šคํฌ๋ฆฝํŠธ์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค.

let startPrice = 10
let startHeight = 1000
let interval = 1000
#ะฝะฐ ัะบะพะปัŒะบะพ ะฟั€ะพั†ะตะฝั‚ะพะฒ ั†ะตะฝะฐ ัƒะฒะตะปะธั‡ะธะฒะฐะตั‚ัั ะทะฐ ะพะดะธะฝ ัˆะฐะณ
let raise = 5
 
match tx {
  case t: TransferTransaction | MassTransferTransaction => false
  case e: ExchangeTransaction =>
    e.price == startPrice + ((height - startHeight) / interval) * (100 + raise) / 100
    && !isDefined(e.sellOrder.assetPair.priceAsset)
  case _ => true
}


๊ฐ„๊ฒฉ๊ฑฐ๋ž˜

๋˜ํ•œ ์Šคํฌ๋ฆฝํŠธ ๋•๋ถ„์— ์Šค๋งˆํŠธ ์ž์‚ฐ์˜ ๊ฑฐ๋ž˜๋ฅผ ๋ฏธ๋ฆฌ ์ •ํ•ด์ง„ ๊ฐ„๊ฒฉ์œผ๋กœ ์ œํ•œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๊ทธ๋Ÿฌํ•œ ์Šคํฌ๋ฆฝํŠธ์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค.

let startHeight = 10000
let interval = 44000
let limit = 1500
 
match tx {
  case t: TransferTransaction | MassTransferTransaction | ExchangeTransaction =>
    (height - startHeight) % interval < limit
  case _ => true
}

์Šคํฌ๋ฆฝํŠธ์—์„œ ์šฐ๋ฆฌ๋Š” ๊ฑฐ๋ž˜ ์‹œ์ž‘๋ถ€ํ„ฐ ์‹œ์ž‘๋†’์ด ์ดํ•˜ ์ œํ•œ ๊ฐ„๊ฒฉ. ๊ฐ„๊ฒฉ์˜ ๊ธธ์ด๋Š” ํ•„๋“œ์— ์ง€์ •๋œ ๋ธ”๋ก ์ˆ˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ฐ„๊ฒฉ.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€