Skip to content

Instantly share code, notes, and snippets.

@yukihirai0505
Last active June 19, 2019 09:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yukihirai0505/f9bd6806ae87f117d83abe74248b4d49 to your computer and use it in GitHub Desktop.
Save yukihirai0505/f9bd6806ae87f117d83abe74248b4d49 to your computer and use it in GitHub Desktop.
WAVES IDE Mocha Test
{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
let senderPk = base58'hoge'
@Verifier(tx)
func verify() = {
match tx {
case d: SetScriptTransaction => sigVerify(tx.bodyBytes, tx.proofs[0], senderPk)
case d: DataTransaction => sigVerify(tx.proofs[0], tx.bodyBytes, senderPk)
case _=> false
}
}
const accountAseed = "hoge"
const accountAAddress = "fuga"
const accountBseed = "piyo"
const accountBAddress = "foo"
console.log("address with waves:")
console.log(address(accountAseed))
it('transfer A -> B', async function() {
let tx = await broadcast(transfer({
amount: 500000000,
recipient: accountBAddress
}, accountAseed))
await waitForTx(tx.id)
console.log(JSON.stringify(tx))
})
it('transfer B -> A', async function() {
let tx = await broadcast(transfer({
amount: 100000000,
recipient: accountAAddress
}, accountBseed))
await waitForTx(tx.id)
console.log(JSON.stringify(tx))
})
it('data transaction', async function() {
let aboutObject = {
"name": "Aleksei Pupyshev",
"occupation": "Founder @ Ventuary Lab"
}
let aboutString = JSON.stringify(aboutObject)
let tx = await broadcast(data({
data: [
{
key: "web3-online-course-user-data",
value: aboutString
}
]
}, accountAseed))
await waitForTx(tx.id)
})
{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
let alicePubKey = base58'hoge'
let bobPubKey = base58'fuga'
let cooperPubKey = base58'piyo'
@Verifier(tx)
func verify() = {
let alice1 = sigVerify(tx.bodyBytes, tx.proofs[0], alicePubKey)
let alice2 = sigVerify(tx.bodyBytes, tx.proofs[1], alicePubKey)
let alice3 = sigVerify(tx.bodyBytes, tx.proofs[2], alicePubKey)
let bob1 = sigVerify(tx.bodyBytes, tx.proofs[0], bobPubKey)
let bob2 = sigVerify(tx.bodyBytes, tx.proofs[1], bobPubKey)
let bob3 = sigVerify(tx.bodyBytes, tx.proofs[2], bobPubKey)
let cooper1 = sigVerify(tx.bodyBytes, tx.proofs[0], cooperPubKey)
let cooper2 = sigVerify(tx.bodyBytes, tx.proofs[1], cooperPubKey)
let cooper3 = sigVerify(tx.bodyBytes, tx.proofs[2], cooperPubKey)
let aliceAndBob = (alice1 && bob2) || (alice1 && bob3) || (alice2 && bob1) || (alice2 && bob3) || (alice3 && bob1) || (alice3 && bob2)
let aliceAndCooper = (alice1 && cooper2) || (alice1 && cooper3) || (alice2 && cooper1) || (alice2 && cooper3) || (alice3 && cooper1) || (alice3 && cooper2)
let bobAndCooper = (cooper1 && bob2) || (cooper1 && bob3) || (cooper2 && bob1) || (cooper2 && bob3) || (cooper3 && bob1) || (cooper3 && bob2)
match tx {
case _ => aliceAndBob || aliceAndCooper || bobAndCooper
}
}
const accountAliceSeed = "seed"
const accountBobSeed = "seed"
const accountBobAddress = "hoge"
const FEE = 500000
it('multisig transfer', async function() {
let txObjectSignedAlice = transfer({amount: 100000, recipient: accountBobAddress, fee:FEE}, accountAliceSeed)
let txObjectSignedAliceBob = transfer(txObjectSignedAlice, accountBobSeed)
let tx = await broadcast(txObjectSignedAliceBob)
await waitForTx(tx.id)
console.log(JSON.stringify(tx))
})
{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
let bobPubKey = base58'DzRrJ9Jz5mDibCKWSFcczbZ39W9TcmtssLqFWZyR8fSG'
@Verifier(tx)
func verify() = {
match tx {
case d: SetScriptTransaction => sigVerify(tx.bodyBytes, tx.proofs[0], bobPubKey)
case d: DataTransaction => sigVerify(tx.proofs[0], tx.bodyBytes, bobPubKey)
case _=> false
}
}
@Callable(i)
func purchase() = {
let pmt = extract(i.payment)
if (isDefined(pmt.assetId)) then throw("can use WAVES only at the moment")
else {
let customerAddress = toBase58String(i.caller.bytes)
let price = match getInteger(this, "item_A_coupon_price") {
case a:Int => a
case _ => 0
}
if ( pmt.amount < price ) then throw("purchase amount cannot be less than item price")
else if ( pmt.amount > price ) then throw("purchase amount cannot be higher than item price")
else {
WriteSet([
DataEntry("status:purchase_item_A_customer" + customerAddress, "confirmed"),
DataEntry("price:purchase_item_A_customer" + customerAddress, price)
])
}
}
}
it('save item', async function() {
let tx = await broadcast(data({
data: [
{
key: "item_A_coupon_price",
value: 5000000
}
],
fee:FEE
}, accountBobSeed))
await waitForTx(tx.id)
})
it('dapp invoke purchase', async function() {
let txObjectSignedCooper = invokeScript({
dApp: accountBobAddress,
call: {
function: "purchase",
args:[]
},
payment: [{amount: 5000000, asset:null}]
}, accoumtCooperSeed)
let tx = await broadcast(txObjectSignedCooper)
await waitForTx(tx.id)
console.log(JSON.stringify(tx))
})
@Callable(i)
func purchase(item: String) = {
let pmt = extract(i.payment)
if (isDefined(pmt.assetId)) then throw("can use WAVES only at the moment")
else {
let customerAddress = toBase58String(i.caller.bytes)
let price = match getInteger(this, "item_" + item + "_coupon_price") {
case a:Int => a
case _ => 0
}
if ( pmt.amount < price ) then throw("purchase amount cannot be less than item price")
else if ( pmt.amount > price ) then throw("purchase amount cannot be higher than item price")
else {
WriteSet([
DataEntry("status:purchase_item_" + item + "_customer" + customerAddress, "confirmed"),
DataEntry("price:purchase_item_" + item + "_customer" + customerAddress, price)
])
}
}
}
{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
let NONE = "none"
func getNumberByKey(key: String) = {
let num = match getInteger(this, key) {
case a: Int => a
case _ => 0
}
num
}
func getStrByKey(key: String) = {
let str = match getString(this, key) {
case a: String => a
case _ => NONE
}
str
}
func getKeyItemPrice(item: String) = {
item + "_price"
}
func getValueItemPrice(item: String) = {
getNumberByKey(getKeyItemPrice(item))
}
func getKeyUserItemCounter(user: String, item: String) = {
item + "_" + user + "_cnt"
}
func getValueUserItemCounter(user: String, item: String) = {
getNumberByKey(getKeyUserItemCounter(user, item))
}
func getKeyItem(supplier: String, title: String) = {
"item_" + toBase58String(sha256(toBytes(supplier + title)))
}
func getKeyItemData(item: String) = {
item + "_data"
}
func getKeyItemSupplier(item: String) = {
item + "_owner"
}
func getValueItemSupplier(item: String) = {
getStrByKey(getKeyItemSupplier(item))
}
func getKeyBalanceSupplier(account: String) = {
account + "_balance"
}
func getValueBalanceSupplier(account: String) = {
getNumberByKey(getKeyBalanceSupplier(account))
}
let VOTERS = 3
let QUORUM = 2
let VOTING = "voting"
let REVEAL = "reveal"
let FEATURED = "featured"
let DELISTED = "delisted"
func getKeyCommit(item: String, user: String) = {
item + "_" + user + "_commit"
}
func getValueCommit(item: String, user: String) = {
getStrByKey(getKeyCommit(item, user))
}
func getKeyCommitsCount(item: String) = {
item + "_comcnt"
}
func getValueCommitsCount(item: String) = {
getNumberByKey(getKeyCommitsCount(item))
}
func getKeyReveal(item: String, user: String) = {
item + "_" + user + "_reveal"
}
func getValueReveal(item: String, user: String) = {
getStrByKey(getKeyReveal(item, user))
}
func getKeyItemStatus(item: String) = {
item + "_status"
}
func getValueItemStatus(item: String) = {
getStrByKey(getKeyItemStatus(item))
}
func getKeyVoteCount(item: String, vote: String ) = {
item + "_res:" + vote
}
func getValueVoteCount(item: String, vote: String) = {
getNumberByKey(getKeyVoteCount(item, vote))
}
@Callable(i)
func addItem(title: String, price: Int, data: String) = {
let supplierAddress = toBase58String(i.caller.bytes)
let item = getKeyItem(supplierAddress, title)
if ( price <= 0 ) then throw("purchase amount cannot be less than item price")
else if ( getValueItemSupplier(item) != NONE ) then throw("an item is already exist")
else {
WriteSet([
DataEntry(getKeyItemSupplier(item), supplierAddress),
DataEntry(getKeyItemPrice(item), price),
DataEntry(getKeyItemData(item), data)
])
}
}
@Callable(i)
func purchase(item: String) = {
let pmt = extract(i.payment)
if (isDefined(pmt.assetId)) then throw("WAVES only at the moment")
else {
let userAddress = toBase58String(i.caller.bytes)
let price = getValueItemPrice(item)
let supplierAddress = getValueItemSupplier(item)
if ( pmt.amount < price ) then throw("purchase amount cannot be less than item price")
else if ( pmt.amount > price ) then throw("purchase amount cannot be higher than item price")
else if (supplierAddress == NONE) then throw("supplier does not exist")
else {
WriteSet([
DataEntry(getKeyUserItemCounter(userAddress, item), getValueUserItemCounter(userAddress, item) + 1),
DataEntry(getKeyBalanceSupplier(supplierAddress), getValueBalanceSupplier(supplierAddress) + pmt.amount)
])
}
}
}
@Callable(i)
func withdraw() = {
let supplierAddress = toBase58String(i.caller.bytes)
let balance = getValueBalanceSupplier(supplierAddress)
if ( balance <= 0 ) then throw("insufficient balance")
else ScriptResult(
WriteSet([
DataEntry(getKeyBalanceSupplier(supplierAddress), 0)
]),
TransferSet([ScriptTransfer(addressFromStringValue(supplierAddress), balance, unit)])
)
}
@Callable(i)
func voteCommit(item: String, hash: String) = {
let user = toBase58String(i.caller.bytes)
let commits = getValueCommitsCount(item)
let status = getValueItemStatus(item)
if ( commits >= VOTERS) then throw("reached max num of voters")
else if (getValueCommit(item, user) != NONE) then throw("user has already participated")
else if (getKeyItemSupplier(item) == NONE) then throw("item does not exist")
else if (status != NONE && status != VOTING) then throw("voting is not possible")
else {
WriteSet([
DataEntry(getKeyCommit(item, user), hash),
DataEntry(getKeyCommitsCount(item), commits + 1),
DataEntry(getKeyItemStatus(item), if(commits == VOTERS) then REVEAL else VOTING)
])
}
}
@Callable(i)
func voteReveal(item: String, vote: String, salt: String) = {
let user = toBase58String(i.caller.bytes)
let status = getValueItemStatus(item)
let newVoteCount = getValueVoteCount(item, vote) + 1
if ( toBase58String(sha256(toBytes(vote + salt))) != getValueCommit(item, user) )
then throw("reveal data is not valid")
else if (getValueCommitsCount(item) < VOTERS) then throw("max num of voters hasn't reached yet")
else if (getValueReveal(item, user) != NONE) then throw("user has already participated")
else if (status != VOTING && status != REVEAL) then throw("wrong status")
else if (vote != FEATURED && vote != DELISTED) then throw("wrong vote")
else if (status == FEATURED || status == DELISTED) then throw("vote has finished")
else {
WriteSet([
DataEntry(getKeyReveal(item, user), vote),
DataEntry(getKeyVoteCount(item, vote), newVoteCount),
DataEntry(getKeyItemStatus(item), if(newVoteCount >= QUORUM) then vote else REVEAL)
])
}
}
let datajson = {
"title": "🔹 TX-Shirt with 💝",
"coupon_price": 10000000,
"old_price": 1000000000,
"new_price": 100000000,
"address": "Universe",
"description": "I want you t make love, not war, I know you've heard it before",
"image": "https://bit.ly/2EXTghg"
}
let dappAddress = "3MuxPBRKTS14onJi6mHtb4tPnnzguYGA5VK"
let accountDappSeed = "exotic intact valve short boy swallow vital frown brown catch follow unique"
let accountSupplierSeed = "rural business receive excuse head genre brain inside busy near achieve click"
let accountCustomerSeed = "label radio luxury sustain angry reduce universe safe force ride jungle strategy"
it('add item', async function() {
let ts = invokeScript({
dApp: dappAddress,
call: {
function: "addItem",
args: [
{ type: "string", value: datajson.title },
{ type: "integer", value: datajson.coupon_price },
{ type: "string", value: JSON.stringify(datajson) },
]
},
payment: []
}, accountDappSeed)
let tx = await broadcast(ts)
await waitForTx(tx.id)
})
it('purchase item', async function() {
let item = "item_7BC1qSdY4SAVzsv7U1gnmThnCHoPFHY83yzxBunfhVrr"
let ts = invokeScript({
dApp: dappAddress,
call: {
function: "purchase",
args:[
{ type:"string", value: item }
]
},
payment: [{amount: datajson.coupon_price, asset:null}]
}, accountCustomerSeed)
let tx = await broadcast(ts)
await waitForTx(tx.id)
})
it('withdraw funds', async function() {
let ts = invokeScript({
dApp: dappAddress,
call: {
function: "withdraw",
args:[]
},
payment: []
}, accountSupplierSeed)
let tx = await broadcast(ts)
await waitForTx(tx.id)
})
let commits = [
"G8ZMEiXEGefpEdgEFN5mYr6oEEABJrtcBBLkZf6Ujmcq",
"Bf2yysmAoroXAzVidK1wxuVYpRGLy1nWe6cNAGXBf5Hi",
"ACHSFMGY7bp3aHryCLYc499XvojeGrgBp59zSvwgLnkQ"
]
let reveals = ["delisted", "featured", "featured"]
let salts = ["random1", "random2", "random3"]
let seeds = [accountDappSeed, accountCustomerSeed, accountSupplierSeed]
it('vote commit', async function() {
let item = "item_Augw77mooMyV4SkvDsuQfhcYP9UeUwt47rMuvhwWo2KU"
let user = 2
let ts = invokeScript({
dApp: dappAddress,
call: {
function: "voteCommit",
args:[
{type: "string", value: item},
{type: "string", value: commits[user]},
]
},
payment: []
}, seeds[user])
let tx = await broadcast(ts)
await waitForTx(tx.id)
})
it('vote reveal', async function() {
let item = "item_Augw77mooMyV4SkvDsuQfhcYP9UeUwt47rMuvhwWo2KU"
let user = 2
let ts = invokeScript({
dApp: dappAddress,
call: {
function: "voteReveal",
args:[
{type: "string", value: item},
{type: "string", value: reveals[user]},
{type: "string", value: salts[user]},
]
},
payment: []
}, seeds[user])
let tx = await broadcast(ts)
await waitForTx(tx.id)
})
const seed = "hoge"
console.log('issuer address: ' + address(seed))
it('custom currency token', async function() {
const tokenParamsCustomCurrency = {
name: "wEUR ex1",
quantity: 1000000,
decimals: 2,
reissuable: false,
description: "hoge"
};
const signedIssueTx = issue(tokenParamsCustomCurrency, seed);
let tx = await broadcast(signedIssueTx);
await waitForTx(tx.id);
console.log("tx / token id: " + tx.id)
})
it('custom indivisible token', async function() {
const tokenParamsCustomCurrency = {
name: "ice cream coupon",
quantity: 100,
decimals: 0,
reissuable: true,
description: "hoge"
};
const signedIssueTx = issue(tokenParamsCustomCurrency, seed);
let tx = await broadcast(signedIssueTx);
await waitForTx(tx.id);
console.log("tx / token id: " + tx.id)
})
it('re-issue coupon smart token', async function() {
const tokenParams = {
quantity: 10,
assetId: '5ZD7sYLzmc2dtiDvabXyryhHbzftHc2nZkT9WQNPFBDP',
reissuable: true
};
const signedIssueTx = reissue(tokenParams, seed);
let tx = await broadcast(signedIssueTx);
await waitForTx(tx.id);
console.log("tx / token id: " + tx.id)
})
it('barn custom token', async function() {
const burnCustomeTokenParams = {
assetId: '5ZD7sYLzmc2dtiDvabXyryhHbzftHc2nZkT9WQNPFBDP',
quantity: 10
};
const signedIssueTx = burn(burnCustomeTokenParams, seed);
let tx = await broadcast(signedIssueTx);
await waitForTx(tx.id);
console.log("burn tx id: " + tx.id)
})
{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
let assetId = base58'5ZD7sYLzmc2dtiDvabXyryhHbzftHc2nZkT9WQNPFBDP'
@Callable(i)
func deposit() = {
let pmt = extract(i.payment)
if (pmt.assetId != assetId) then throw("ice cream token only at the moment")
else {
let currentKey = toBase58String(i.caller.bytes)
let currentAmount = match getInteger(this, currentKey) {
case a:Int => a
case _ => 0
}
let newAmount = currentAmount + pmt.amount
WriteSet([
DataEntry(currentKey, newAmount)
])
}
}
@Callable(i)
func withdraw(amount: Int) = {
let currentKey = toBase58String(i.caller.bytes)
let currentAmount = match getInteger(this, currentKey) {
case a:Int => a
case _ => 0
}
let newAmount = currentAmount - amount
if (amount < 0) then throw("Can't withdraw negative amount")
else if (newAmount < 0) then throw("Not enough balancez")
else ScriptResult(
WriteSet([
DataEntry(currentKey, newAmount)
]),
TransferSet([
ScriptTransfer(i.caller, amount, assetId)
])
)
}
const assetId = '5ZD7sYLzmc2dtiDvabXyryhHbzftHc2nZkT9WQNPFBDP'
const seeddapps = 'hoge'
it('deposit', async function() {
let ts = invokeScript({
dApp: address(seeddapps),
call: {
function: "deposit",
args: []
},
payment: [{
amount: 10,
assetId: assetId
}]
}, seed)
let itx = await broadcast(ts)
await waitForTx(itx.id)
})
it('withdraw funds: custom tokens', async function() {
let ts = invokeScript({
dApp: address(seeddapps),
call: {
function: "withdraw",
args: [{
type: "integer",
value: 5
}]
},
payment: []
}, seed)
let itx = await broadcast(ts)
await waitForTx(itx.id)
})
const seed = "hoge"
const FEE = 100400000
console.log('issuer address: ' + address(seed))
it('non-fungible token (NFT)', async function() {
const tokenParamsCustomeIndivisible = {
name: "special gift",
quantity: 1,
decimals: 0,
reissuable: false,
description: "hoge",
fee: FEE
};
const signedIssueTx = issue(tokenParamsCustomeIndivisible, seed);
let tx = await broadcast(signedIssueTx);
await waitForTx(tx.id);
console.log("tx / token id: " + tx.id)
})
{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE EXPRESSION #-}
{-# SCRIPT_TYPE ASSET #-}
match tx {
case d: ExchangeTransaction => true
case _=> false
}
{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE EXPRESSION #-}
{-# SCRIPT_TYPE ASSET #-}
let expiration = 578400
match tx {
case br : BurnTransaction | ReissueTransaction => {
let supplier = extract(assetInfo(br.assetId))
supplier.issuerPublicKey == tx.senderPublicKey
}
case e : ExchangeTransaction => {
let withWaves = (!isDefined(e.sellOrder.assetPair.priceAsset)
|| !isDefined(e.sellOrder.assetPair.amountAsset))
height <= expiration && withWaves
}
case tr : TransferTransaction => height <= expiration
case _ => false
}
it('issue coupon smart token', async function() {
const tokenParams = {
name: "my bazaar coupon",
quantity: 100,
decimals: 0,
reissuable: true,
script: compile(file('coupon-token')),
description: "hoge",
fee: 100400000
};
const signedIssueTx = issue(tokenParams, seed);
let tx = await broadcast(signedIssueTx);
await waitForTx(tx.id);
console.log("tx / token id: " + tx.id)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment