tx · 9C71e3yn4YfrUEd2rSiq4v1SoZv7wLftWAv47c8cHwrN

3PAi1ePLQrYrY3jj9omBtT6isMkZsapbmks:  -0.01400000 Waves

2022.04.05 14:04 [3060459] smart account 3PAi1ePLQrYrY3jj9omBtT6isMkZsapbmks > SELF 0.00000000 Waves

{ "type": 13, "id": "9C71e3yn4YfrUEd2rSiq4v1SoZv7wLftWAv47c8cHwrN", "fee": 1400000, "feeAssetId": null, "timestamp": 1649156642292, "version": 2, "chainId": 87, "sender": "3PAi1ePLQrYrY3jj9omBtT6isMkZsapbmks", "senderPublicKey": "XrNmTusDFaLSz3wAjmdfcyC5h6uYyVbpdh18758UpFv", "proofs": [ "2uCpppeyLvhsKjcyT9Ejgk7NDwzHarbYMBF1rqoag2cD5df8v2cocm5aGSWXy5rfZtbtPKov5dFntuTHE9EZ5vi5" ], "script": "base64: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X29yYWNsZUFkZHJlc3MBAAAAEWdldEJyZWVkZXJBZGRyZXNzAAAAAAkBAAAAB0FkZHJlc3MAAAABCQACWQAAAAEJAQAAABR0cnlHZXRTdHJpbmdFeHRlcm5hbAAAAAIJAQAAAAlnZXRPcmFjbGUAAAAAAgAAABVzdGF0aWNfYnJlZWRlckFkZHJlc3MBAAAADWdldEVnZ0Fzc2V0SWQAAAAACQACWQAAAAEJAQAAABR0cnlHZXRTdHJpbmdFeHRlcm5hbAAAAAIJAQAAAAlnZXRPcmFjbGUAAAAAAgAAABFzdGF0aWNfZWdnQXNzZXRJZAEAAAAIYXNTdHJpbmcAAAABAAAABXZhbHVlBAAAAAckbWF0Y2gwBQAAAAV2YWx1ZQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAGU3RyaW5nBAAAAAZzdHJpbmcFAAAAByRtYXRjaDAFAAAABnN0cmluZwkAAAIAAAABAgAAABx3cm9uZyB0eXBlLCBleHBlY3RlZDogU3RyaW5nAQAAAAVhc0ludAAAAAEAAAAFdmFsdWUEAAAAByRtYXRjaDAFAAAABXZhbHVlAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAANJbnQEAAAAA2ludAUAAAAHJG1hdGNoMAUAAAADaW50CQAAAgAAAAECAAAAGXdyb25nIHR5cGUsIGV4cGVjdGVkOiBJbnQBAAAADm1hbmlwdWxhdGVOYW1lAAAAAwAAAAlhc3NldE5hbWUAAAAIcG9zaXRpb24AAAAEY2hhcgkAASwAAAACCQABLAAAAAIJAAEvAAAAAgUAAAAJYXNzZXROYW1lCQAAZQAAAAIFAAAACHBvc2l0aW9uAAAAAAAAAAABBQAAAARjaGFyCQEAAAAJdGFrZVJpZ2h0AAAAAgUAAAAJYXNzZXROYW1lCQAAZQAAAAIAAAAAAAAAABAFAAAACHBvc2l0aW9uAQAAABBpdGVtSXNJbkNvb2xEb3duAAAAAgAAAAxhcnRlZmFjdE5hbWUAAAAKYXJ0ZWZhY3RJZAQAAAARdW5zdGFrZUhlaWdodExhc3QJAQAAAA10cnlHZXRJbnRlZ2VyAAAAAQkBAAAAEGtleVVuc3Rha2VIZWlnaHQAAAACBQAAAAxhcnRlZmFjdE5hbWUFAAAACmFydGVmYWN0SWQEAAAADmNvb2xk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ZmFjdE5hbWUJAAACAAAAAQIAAAAdWW91IGNhbid0IHN0YWtlIHRoaXMgYXJ0YWZlY3QJAAACAAAAAQIAAAAPSW52YWxpZCBwYXltZW50AAAAAWkBAAAAC3Vuc3Rha2VJdGVtAAAAAQAAAAxhcnRlZmFjdE5hbWUDCQEAAAAPY29udGFpbnNFbGVtZW50AAAAAgUAAAALYWxsQXJ0ZWZhY3QFAAAADGFydGVmYWN0TmFtZQQAAAAHaW52b2tlcgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAACmFydGVmYWN0SWQJAQAAAAx0cnlHZXRTdHJpbmcAAAABCQEAAAAQa2V5QXJ0ZWZhY3RPd25lcgAAAAIFAAAADGFydGVmYWN0TmFtZQUAAAAHaW52b2tlcgMJAAAAAAAAAgUAAAAKYXJ0ZWZhY3RJZAIAAAAACQAAAgAAAAEJAAEsAAAAAgIAAAAQWW91IGRpZG50IHN0YWtlIAUAAAAMYXJ0ZWZhY3ROYW1lCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAQa2V5VW5zdGFrZUhlaWdodAAAAAIFAAAADGFydGVmYWN0TmFtZQUAAAAKYXJ0ZWZhY3RJZAUAAAAGaGVpZ2h0CQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgAAAAAAAAAAAQkAAlkAAAABBQAAAAphcnRlZmFjdElkCQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEJAQAAABBrZXlBcnRlZmFjdE93bmVyAAAAAgUAAAAMYXJ0ZWZhY3ROYW1lBQAAAAdpbnZva2VyBQAAAANuaWwJAAACAAAAAQIAAAAbVGhpcyBhcnRlZmFjdCBkb2Vzbid0IGV4aXN0AAAAAWkBAAAAB3ByZUluaXQAAAAACQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAAABxzdGF0aWNfQVJULUxBS0VfZmFybWluZ1Nsb3RzAAAAAAAAAADICQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAAABxzdGF0aWNfQVJULUxBS0VfZmFybWluZ0Jvb3N0AAAAAAAAAAACCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAA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", "height": 3060459, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5rLA6NLHwVoD8RAXZzAhbsLQ68pPq6hxGZzYBmmcDUDH Next: 3ZZzWcyk4MP3ZoMBnCBmPumQoVqB9rPFHLkwCiAC4yPQ Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let perchPrice = (100 * 1000000)
4+func keyArtefactOwner (artefactName,owner) = (((artefactName + "_") + owner) + "_owner")
55
6-let scale = 10000
76
8-let scale2 = 1000000
7+func keyUnstakeHeight (artefactName,artefactId) = (((artefactName + "_") + artefactId) + "_unstake_height")
8+
9+
10+func getProcessFinishHeightKey (address,txId) = (((address + "_") + toBase58String(txId)) + "_fh")
11+
12+
13+let devAddress = base58'3P44yqcpfhPF2iC1nptm2ZJCTaN7VYhz9og'
14+
15+let eggsNeeded = (3 * 100000000)
16+
17+let artefactsLimit = (301 + 600)
18+
19+let freeGenes = ["A", "B", "C", "D", "E"]
20+
21+let oldArtefacts = ["ART-LAKE", "ART-HOUSE", "ART-BIGHOUSE", "ART-FIXGENE", "ART-FREEGENE", "ART-MIRROR", "ART-POMP", "ART-CAPE", "ART-HAT", "ART-CUSTOMDUCK"]
22+
23+let artefacts = ["ART-XMISTL", "ART-XHAT", "ART-XSCARF", "ART-XSWEATER", "ART-XSOCK", "ART-XTREE"]
24+
25+let stakeableWithLock = ["ART-LAKE", "ART-XTREE"]
26+
27+let stakeableWithoutLock = ["ART-XMISTL"]
28+
29+let allStakeable = (stakeableWithoutLock ++ stakeableWithLock)
30+
31+let allArtefact = (artefacts ++ oldArtefacts)
32+
33+func tryGetString (key) = match getString(this, key) {
34+ case a: String =>
35+ a
36+ case _ =>
37+ ""
38+}
39+
40+
41+func tryGetInteger (key) = match getInteger(this, key) {
42+ case a: Int =>
43+ a
44+ case _ =>
45+ 0
46+}
47+
48+
49+func getRandomNumber (variants,txId,finishHeight,offset) = {
50+ let randomSeedBlock = value(blockInfoByHeight((finishHeight - 1)))
51+ let randomHash = sha256(((base58'items' + txId) + value(randomSeedBlock.vrf)))
52+ (toInt(randomHash, offset) % variants)
53+ }
54+
55+
56+func getRandomArtefact (boxId,h) = {
57+ let randomNumber = getRandomNumber(6, boxId, h, 1)
58+artefacts[randomNumber]
59+ }
60+
61+
62+func getRandomGenes (txId,h) = {
63+ let randomNumber = getRandomNumber(6, txId, h, 2)
64+freeGenes[randomNumber]
65+ }
66+
67+
68+func checkArtefactDetails (assetId) = {
69+ let asset = value(assetInfo(assetId))
70+ let assetName = value(asset.name)
71+ if (if (containsElement(allArtefact, assetName))
72+ then (asset.issuer == this)
73+ else false)
74+ then assetName
75+ else throw("Invalid artefact")
76+ }
77+
978
1079 func tryGetStringExternal (address,key) = match getString(address, key) {
1180 case a: String =>
1584 }
1685
1786
18-func tryGetString (key) = tryGetStringExternal(this, key)
19-
20-
2187 func getOracle () = Address(fromBase58String(tryGetString("static_oracleAddress")))
22-
23-
24-func getEggAssetId () = fromBase58String(tryGetStringExternal(getOracle(), "static_eggAssetId"))
25-
26-
27-func getIncubatorAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_incubatorAddress")))
28-
29-
30-func getRebirthAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_rebirthAddress")))
31-
32-
33-func getSwopPromoAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_swopPromoAddress")))
3488
3589
3690 func getBreederAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_breederAddress")))
3791
3892
39-func getRefContractAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_refContractAddress")))
40-
41-
42-func getItemsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_itemsAddress")))
43-
44-
45-let RefererReward = 5
46-
47-func getRewardPerBlock () = 684
48-
49-
50-func isLocked () = {
51- let masterAddress = Address(base58'3PEPftf2kWZDmAaWBjs6BUJa9957kiA2PkU')
52- match getInteger(masterAddress, "egglock") {
53- case b: Int =>
54- b
55- case _ =>
56- 0
57- }
58- }
59-
60-
61-func tryGetInteger (key) = match getInteger(this, key) {
62- case b: Int =>
63- b
64- case _ =>
65- 0
66-}
67-
68-
69-func isUserBlacklisted (address) = false
70-
71-
72-func getAssetOrigin (generation) = if ((generation == "G"))
73- then getIncubatorAddress()
74- else getBreederAddress()
75-
76-
77-func getAssetRarity (genotype,generation) = {
78- let quantity = valueOrErrorMessage(getInteger(getAssetOrigin(generation), (("stats_" + genotype) + "_quantity")), (("stats_" + genotype) + "_quantity not found"))
79- let power = pow((10000 / quantity), 4, 5, 1, 2, FLOOR)
80- if ((power > 0))
81- then power
82- else 2
83- }
93+func getEggAssetId () = fromBase58String(tryGetStringExternal(getOracle(), "static_eggAssetId"))
8494
8595
8696 func asString (value) = match value {
99109 }
100110
101111
102-func getAssetFarmingPower (assetId,address) = if (if ((value(assetInfo(assetId)).issuer == getBreederAddress()))
103- then true
104- else (value(assetInfo(assetId)).issuer == getIncubatorAddress()))
105- then {
106- let assetName = value(assetInfo(assetId)).name
107- let generation = take(takeRight(assetName, 2), 1)
108- let farmGen = asString(invoke(getBreederAddress(), "getGenFromName", [assetName], nil))
109- if ((farmGen == farmGen))
110- then {
111- let farmBoost = asInt(invoke(getItemsAddress(), "calculateFarmingPowerBoost", [toBase58String(assetId), address], nil))
112- if ((farmBoost == farmBoost))
113- then {
114- let rarity = getAssetRarity(farmGen, generation)
115- let totalFarmingPower = (rarity + fraction(rarity, farmBoost, 100))
116- $Tuple2(farmGen, totalFarmingPower)
117- }
118- else throw("Strict value is not equal to itself.")
119- }
120- else throw("Strict value is not equal to itself.")
121- }
122- else throw("not valid NFT")
112+func manipulateName (assetName,position,char) = ((take(assetName, (position - 1)) + char) + takeRight(assetName, (16 - position)))
123113
124114
125-func getLastKnownAssetFarmingPower (address,assetId) = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_farmingPower"))
126-
127-
128-func getAssetsByGen (gen) = {
129- let s = tryGetString(("assets_" + gen))
130- if ((s == ""))
131- then nil
132- else split(s, ",")
133- }
134-
135-
136-func calcInterest (previousInterest,previousInterestHeight,totalFarmingPower) = (previousInterest + (((scale * getRewardPerBlock()) * (height - previousInterestHeight)) / totalFarmingPower))
137-
138-
139-func getCurrentInterest () = if ((tryGetInteger("total_farmingPower") > 0))
140- then {
141- let previousInterest = tryGetInteger("total_lastCheckInterest")
142- let previousInterestHeight = tryGetInteger("total_lastCheckInterestHeight")
143- let totalFarmingPower = tryGetInteger("total_farmingPower")
144- calcInterest(previousInterest, previousInterestHeight, totalFarmingPower)
145- }
146- else if ((tryGetInteger("total_startHeight") != 0))
147- then tryGetInteger("total_lastCheckInterest")
148- else throw("farming is not launched, yet")
149-
150-
151-func calcAssetRewardDelta (address,assetId,assetFarmingPower) = {
152- let lastCheckAssetInterest = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_lastCheckInterest"))
153- let currentInterest = getCurrentInterest()
154- (assetFarmingPower * (currentInterest - lastCheckAssetInterest))
155- }
156-
157-
158-func addAssetIdToGenEntry (assetId,assetGen) = {
159- let currentValue = tryGetString((("assets_" + assetGen) + "_locked"))
160- if ((currentValue == ""))
161- then assetId
162- else ((currentValue + ",") + assetId)
163- }
164-
165-
166-func getStakeResult (address,assetId,assetFarmingPower) = {
167- let asset = toBase58String(assetId)
168-[IntegerEntry("total_farmingPower", (tryGetInteger("total_farmingPower") + assetFarmingPower)), IntegerEntry("total_lastCheckInterest", getCurrentInterest()), IntegerEntry("total_lastCheckInterestHeight", height), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_farmingPower"), assetFarmingPower), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest"), getCurrentInterest())]
169- }
170-
171-
172-func getUnstakeResult (address,assetId,rewardDelta,withdrawnAmount,assetFarmingPower) = {
173- let asset = toBase58String(assetId)
174-[IntegerEntry("total_farmingPower", (tryGetInteger("total_farmingPower") - assetFarmingPower)), IntegerEntry("total_lastCheckInterest", getCurrentInterest()), IntegerEntry("total_lastCheckInterestHeight", height), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_farmingPower"), 0), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest"), getCurrentInterest()), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount")) + (withdrawnAmount * scale2))), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")) + rewardDelta))]
175- }
176-
177-
178-func calculatePerchPrice (address) = {
179- let hasArtefactStaked = tryGetStringExternal(getItemsAddress(), (("ART-XMISTL_" + address) + "_owner"))
180- if ((hasArtefactStaked == ""))
181- then perchPrice
182- else ((perchPrice / 10) * 9)
115+func itemIsInCoolDown (artefactName,artefactId) = {
116+ let unstakeHeightLast = tryGetInteger(keyUnstakeHeight(artefactName, artefactId))
117+ let cooldownPeriod = 240
118+ if ((height > (unstakeHeightLast + cooldownPeriod)))
119+ then false
120+ else true
183121 }
184122
185123
191129
192130
193131 @Callable(i)
194-func init () = if ((i.caller != this))
195- then throw("admin only")
196- else [IntegerEntry("total_startHeight", height)]
132+func calculateFarmingPowerBoost (duckId,address) = {
133+ let lakeBoost = if ((tryGetString(keyArtefactOwner("ART-LAKE", address)) != ""))
134+ then 2
135+ else 0
136+ let xmasTreeBoost = if ((tryGetString(keyArtefactOwner("ART-XTREE", address)) != ""))
137+ then 3
138+ else 0
139+ let totalBoost = (lakeBoost + xmasTreeBoost)
140+ $Tuple2(nil, totalBoost)
141+ }
197142
198143
199144
200145 @Callable(i)
201-func buyPerch (color,refererAddress) = if ((isLocked() > 0))
202- then throw("EGG operations are temporarily locked")
203- else if ((0 > value(indexOf(["B", "R", "G", "Y"], color))))
204- then throw("you need to set color properly")
146+func fixedGene (txIdStr,parentFixedGene,positionFixedGene) = {
147+ let firstPayment = value(i.payments[0])
148+ let firstAssetId = toBase58String(value(firstPayment.assetId))
149+ if ((firstPayment.amount != 1))
150+ then throw("NFT is not attached")
205151 else {
206- let firstPayment = value(i.payments[0])
207- let exactPrice = calculatePerchPrice(toString(i.caller))
208- if ((firstPayment.assetId != getEggAssetId()))
209- then throw(("You can attach only EGG tokens with the following asset id: " + toBase58String(getEggAssetId())))
210- else if ((firstPayment.amount != exactPrice))
211- then throw(("To buy a perch you currently need the following amount of EGGlets: " + toString(exactPrice)))
212- else {
213- let refererRewardForPerch = fraction(firstPayment.amount, RefererReward, 100)
214- let refCall = invoke(getRefContractAddress(), "refPayment", [refererAddress], [AttachedPayment(getEggAssetId(), refererRewardForPerch)])
215- if ((refCall == refCall))
216- then {
217- let perchAmountKey = ((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)
218- let perchAmount = tryGetInteger(perchAmountKey)
219-[IntegerEntry(perchAmountKey, (perchAmount + 1))]
220- }
221- else throw("Strict value is not equal to itself.")
222- }
152+ let artefact = checkArtefactDetails(value(firstPayment.assetId))
153+ if ((artefact != "ART-FIXGENE"))
154+ then throw("You need to attach a ART-FIXGENE artefact")
155+ else {
156+ let txId = fromBase58String(txIdStr)
157+ let finishHeightKey = getProcessFinishHeightKey(toString(i.caller), txId)
158+ let processFinishHeight = getIntegerValue(getBreederAddress(), finishHeightKey)
159+ let duckGenesString = asString(invoke(getBreederAddress(), "generateDuck", [txIdStr, processFinishHeight, parentFixedGene, positionFixedGene, "", 0], nil))
160+ if ((duckGenesString == duckGenesString))
161+ then {
162+ let call = invoke(getBreederAddress(), "finishDuckHatchingItems", [txIdStr, duckGenesString], nil)
163+ if ((call == call))
164+ then [Burn(value(firstPayment.assetId), 1)]
165+ else throw("Strict value is not equal to itself.")
166+ }
167+ else throw("Strict value is not equal to itself.")
168+ }
223169 }
170+ }
224171
225172
226173
227174 @Callable(i)
228-func addFreePerch (address,color) = if ((0 > value(indexOf(["B", "R", "G", "Y"], color))))
229- then throw("you need to set color properly")
230- else if (if (if ((i.caller != getRebirthAddress()))
231- then (i.caller != this)
232- else false)
233- then (i.caller != getSwopPromoAddress())
234- else false)
235- then throw("rebirth and swop promo only")
175+func freeGene (txIdStr) = {
176+ let firstPayment = value(i.payments[0])
177+ let firstAssetId = toBase58String(value(firstPayment.assetId))
178+ if ((firstPayment.amount != 1))
179+ then throw("NFT is not attached")
236180 else {
237- let perchAmountKey = ((("address_" + address) + "_perchesAvailable_") + color)
238- let perchAmount = tryGetInteger(perchAmountKey)
239- $Tuple2([IntegerEntry(perchAmountKey, (perchAmount + 1))], "")
181+ let artefact = checkArtefactDetails(value(firstPayment.assetId))
182+ if ((artefact != "ART-FREEGENE"))
183+ then throw("You need to attach a ART-FREEGENE artefact")
184+ else {
185+ let txId = fromBase58String(txIdStr)
186+ let finishHeightKey = getProcessFinishHeightKey(toString(i.caller), txId)
187+ let processFinishHeight = getIntegerValue(getBreederAddress(), finishHeightKey)
188+ let selectedGene = getRandomGenes(txId, processFinishHeight)
189+ let randomPosition = getRandomNumber(7, txId, processFinishHeight, 3)
190+ let duckGenesString = asString(invoke(getBreederAddress(), "generateDuck", [txIdStr, processFinishHeight, 0, 0, selectedGene, randomPosition], nil))
191+ if ((duckGenesString == duckGenesString))
192+ then {
193+ let call = invoke(getBreederAddress(), "finishDuckHatchingItems", [txIdStr, duckGenesString], nil)
194+ if ((call == call))
195+ then [Burn(value(firstPayment.assetId), 1)]
196+ else throw("Strict value is not equal to itself.")
197+ }
198+ else throw("Strict value is not equal to itself.")
199+ }
240200 }
201+ }
241202
242203
243204
244205 @Callable(i)
245-func stakeNFT () = if ((isLocked() > 0))
246- then throw("EGG operations are temporarily locked")
247- else {
248- let pmt = value(i.payments[0])
249- let assetId = value(value(i.payments[0]).assetId)
250- let address = toString(i.caller)
251- let color = takeRight(value(assetInfo(assetId)).name, 1)
252- let availablePerches = tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color))
253- if ((pmt.amount != 1))
206+func copyDuck () = {
207+ let firstPayment = value(i.payments[0])
208+ let secondPayment = value(i.payments[1])
209+ let firstAssetId = toBase58String(value(firstPayment.assetId))
210+ let children = asInt(invoke(getBreederAddress(), "validateAndGetChildren", [firstAssetId], nil))
211+ if ((children == children))
212+ then if (if ((firstPayment.amount != 1))
213+ then true
214+ else (secondPayment.amount != 1))
254215 then throw("NFT is not attached")
255- else if ((0 >= availablePerches))
256- then throw(("no perches available for the color " + color))
257- else {
258- let $t096749747 = getAssetFarmingPower(assetId, address)
259- let assetGen = $t096749747._1
260- let assetFarmingPower = $t096749747._2
261- let assetRewardDelta = calcAssetRewardDelta(address, toBase58String(assetId), assetFarmingPower)
262- (getStakeResult(address, assetId, assetFarmingPower) ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (availablePerches - 1))])
263- }
264- }
216+ else {
217+ let artefact = checkArtefactDetails(value(secondPayment.assetId))
218+ if ((artefact != "ART-MIRROR"))
219+ then throw("You need to attach a ART-MIRROR artefact")
220+ else {
221+ let nftInfo = value(assetInfo(value(firstPayment.assetId)))
222+ let asset1Gen = split(nftInfo.name, "")
223+ if (if ((asset1Gen[14] == "G"))
224+ then true
225+ else (asset1Gen[14] == "J"))
226+ then throw("You can't mirror this duck")
227+ else {
228+ let duckGen = nftInfo.name
229+ let call = invoke(getBreederAddress(), "createDuckSpecialGenes", [i.caller.bytes, duckGen, children], nil)
230+ if ((call == call))
231+ then [ScriptTransfer(i.caller, 1, firstPayment.assetId), Burn(value(secondPayment.assetId), 1)]
232+ else throw("Strict value is not equal to itself.")
233+ }
234+ }
235+ }
236+ else throw("Strict value is not equal to itself.")
237+ }
265238
266239
267240
268241 @Callable(i)
269-func unstakeNFT (asset) = if (isUserBlacklisted(toString(i.caller)))
270- then throw("Ooops, looks like you lost in one of the Ducksquid games! As you already know, any loss has its consequences, so you will be not able to claim your farming rewards till the end of DuckSquid game. Quack in peace!")
271- else if ((isLocked() > 0))
272- then throw("EGG operations are temporarily locked")
242+func addArteFactToDuck () = {
243+ let firstPayment = value(i.payments[0])
244+ let secondPayment = value(i.payments[1])
245+ let firstAssetId = toBase58String(value(firstPayment.assetId))
246+ if (if ((firstPayment.amount != 1))
247+ then true
248+ else (secondPayment.amount != 1))
249+ then throw("NFT is not attached")
273250 else {
274- let assetId = fromBase58String(asset)
275- let address = toString(i.caller)
276- let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
277- let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
278- let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
279- let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
280- let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
281- let color = takeRight(value(assetInfo(assetId)).name, 1)
282- if ((0 >= assetFarmingPower))
283- then throw("asset not available")
284- else if ((color == "U"))
285- then throw("use another function to unstake Jackpot NFT")
251+ let children = asInt(invoke(getBreederAddress(), "validateAndGetChildren", [firstAssetId], nil))
252+ if ((children == children))
253+ then if ((children == 0))
254+ then throw("You can only pick a sterile NFT-duck")
286255 else {
287- let result = getUnstakeResult(address, assetId, assetRewardDelta, reward, assetFarmingPower)
288- $Tuple2((result ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)) + 1)), ScriptTransfer(i.caller, (reward * 1000000), getEggAssetId()), ScriptTransfer(i.caller, 1, assetId)]), (reward * 1000000))
256+ let artefact = checkArtefactDetails(value(secondPayment.assetId))
257+ if (if ((artefact != "ART-XHAT"))
258+ then (artefact != "ART-POMP")
259+ else false)
260+ then throw("You need to attach a ART-XHAT or ART-POMP artefact")
261+ else {
262+ let nftInfo = value(assetInfo(value(firstPayment.assetId)))
263+ let asset1Gen = split(nftInfo.name, "")
264+ if (if ((asset1Gen[14] == "G"))
265+ then true
266+ else (asset1Gen[14] == "J"))
267+ then throw("You can't mirror this duck")
268+ else if (if ((asset1Gen[5] == "S"))
269+ then true
270+ else (asset1Gen[5] == "T"))
271+ then throw("you already attached a artefact")
272+ else {
273+ let char = if ((artefact == "ART-XHAT"))
274+ then "T"
275+ else if ((artefact == "ART-POMP"))
276+ then "S"
277+ else throw("No char defined")
278+ let oldDuckGen = nftInfo.name
279+ let oldFarmGen = asString(invoke(getBreederAddress(), "getGenFromName", [oldDuckGen], nil))
280+ if ((oldFarmGen == oldFarmGen))
281+ then {
282+ let duckGen = manipulateName(oldDuckGen, 6, char)
283+ let call = invoke(getBreederAddress(), "createDuckSpecialGenes", [i.caller.bytes, duckGen, children], nil)
284+ if ((call == call))
285+ then {
286+ let callReduce = invoke(getBreederAddress(), "reduceRarity", [firstAssetId, oldFarmGen], nil)
287+ if ((callReduce == callReduce))
288+ then [Burn(value(firstPayment.assetId), 1), Burn(value(secondPayment.assetId), 1)]
289+ else throw("Strict value is not equal to itself.")
290+ }
291+ else throw("Strict value is not equal to itself.")
292+ }
293+ else throw("Strict value is not equal to itself.")
294+ }
295+ }
289296 }
297+ else throw("Strict value is not equal to itself.")
290298 }
299+ }
291300
292301
293302
294303 @Callable(i)
295-func stakeJackpot (color) = if ((isLocked() > 0))
296- then throw("EGG operations are temporarily locked")
297- else {
298- let pmt = value(i.payments[0])
299- let assetId = value(pmt.assetId)
300- let address = toString(i.caller)
301- let availablePerches = tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color))
302- let assetIssuer = value(assetInfo(assetId)).issuer
303- if ((pmt.amount != 1))
304- then throw("NFT is not attached")
305- else if (if ((assetIssuer == getIncubatorAddress()))
306- then true
307- else (assetIssuer == getBreederAddress()))
308- then if ((takeRight(value(value(assetInfo(assetId)).name), 1) != "U"))
309- then throw("jackpot only")
310- else if ((0 >= availablePerches))
311- then throw(("no perches available for the color " + color))
312- else (getStakeResult(address, assetId, 100) ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (availablePerches - 1)), StringEntry((((("address_" + toString(i.caller)) + "_asset_") + toBase58String(assetId)) + "_perchColor"), color)])
313- else throw("asset is not valid")
304+func stakeItem () = if (if ((size(i.payments) == 1))
305+ then (i.payments[0].amount == 1)
306+ else false)
307+ then {
308+ let assetId = value(i.payments[0].assetId)
309+ let artefactName = checkArtefactDetails(assetId)
310+ if (containsElement(allStakeable, artefactName))
311+ then if (if (containsElement(stakeableWithLock, artefactName))
312+ then itemIsInCoolDown(artefactName, toBase58String(assetId))
313+ else false)
314+ then throw("Item can't be staked yet, it's in cooldown")
315+ else {
316+ let invoker = toString(i.caller)
317+ let artefactId = tryGetString(keyArtefactOwner(artefactName, invoker))
318+ if ((artefactId == ""))
319+ then [StringEntry(keyArtefactOwner(artefactName, invoker), toBase58String(assetId))]
320+ else throw(("You are already staking " + artefactName))
321+ }
322+ else throw("You can't stake this artafect")
314323 }
324+ else throw("Invalid payment")
315325
316326
317327
318328 @Callable(i)
319-func unstakeJackpot (asset) = if (isUserBlacklisted(toString(i.caller)))
320- then throw("Ooops, looks like you lost in one of the Ducksquid games! As you already know, any loss has its consequences, so you will be not able to claim your farming rewards till the end of DuckSquid game. Quack in peace!")
321- else if ((isLocked() > 0))
322- then throw("EGG operations are temporarily locked")
323- else {
324- let assetId = fromBase58String(asset)
325- let address = toString(i.caller)
326- let color = tryGetString((((("address_" + address) + "_asset_") + asset) + "_perchColor"))
327- let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
328- let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
329- let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
330- let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
331- let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
332- if ((takeRight(value(value(assetInfo(assetId)).name), 1) != "U"))
333- then throw("jackpot only")
334- else if ((assetFarmingPower > 0))
335- then {
336- let result = getUnstakeResult(address, assetId, assetRewardDelta, reward, assetFarmingPower)
337- $Tuple2((result ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)) + 1)), ScriptTransfer(i.caller, (reward * 1000000), getEggAssetId()), ScriptTransfer(i.caller, 1, assetId)]), (reward * 1000000))
338- }
339- else throw("")
340- }
329+func unstakeItem (artefactName) = if (containsElement(allArtefact, artefactName))
330+ then {
331+ let invoker = toString(i.caller)
332+ let artefactId = tryGetString(keyArtefactOwner(artefactName, invoker))
333+ if ((artefactId == ""))
334+ then throw(("You didnt stake " + artefactName))
335+ else [IntegerEntry(keyUnstakeHeight(artefactName, artefactId), height), ScriptTransfer(i.caller, 1, fromBase58String(artefactId)), DeleteEntry(keyArtefactOwner(artefactName, invoker))]
336+ }
337+ else throw("This artefact doesn't exist")
341338
342339
343340
344341 @Callable(i)
345-func claimReward (asset) = if (isUserBlacklisted(toString(i.caller)))
346- then throw("Ooops, looks like you lost in one of the Ducksquid games! As you already know, any loss has its consequences, so you will be not able to claim your farming rewards till the end of DuckSquid game. Quack in peace!")
347- else if ((isLocked() > 0))
348- then throw("EGG operations are temporarily locked")
349- else {
350- let address = toString(i.caller)
351- let assetId = fromBase58String(asset)
352- let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
353- let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
354- let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
355- let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
356- let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
357- if ((0 >= reward))
358- then throw("you have no EGGs to withdraw")
359- else $Tuple2([IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount")) + (reward * scale2))), ScriptTransfer(Address(fromBase58String(address)), (reward * 1000000), getEggAssetId())], (reward * 1000000))
360- }
342+func preInit () = [IntegerEntry("static_ART-LAKE_farmingSlots", 200), IntegerEntry("static_ART-LAKE_farmingBoost", 2), IntegerEntry("static_ART-HOUSE_farmingSlots", 4), IntegerEntry("static_ART-HOUSE_farmingBoost", 30), IntegerEntry("static_ART-BIGHOUSE_farmingSlots", 10), IntegerEntry("static_ART-BIGHOUSE_farmingBoost", 15)]
361343
344+
345+
346+@Callable(i)
347+func issueArtefact (type,receiver) = if ((i.caller == this))
348+ then {
349+ let txIdStr = toBase58String(i.transactionId)
350+ let address = Address(fromBase58String(receiver))
351+ let artefact = Issue(type, "NFT artefact of Waves Ducks game. Drop #2.", 1, 0, false, unit, 0)
352+ let artefactId = calculateAssetId(artefact)
353+[artefact, StringEntry((("artefact_" + toBase58String(artefactId)) + "_type"), type), ScriptTransfer(address, 1, artefactId)]
354+ }
355+ else throw("admin only")
356+
357+
358+
359+@Callable(i)
360+func setLock (n) = if ((i.caller == this))
361+ then [IntegerEntry("global_locked", n)]
362+ else throw("admin only")
363+
364+
365+
366+@Callable(i)
367+func buyArtefact () = if ((lastBlock.timestamp > 1639742400000))
368+ then throw("There are no active sales now... ")
369+ else if ((tryGetInteger("global_locked") > 0))
370+ then throw("contract is temporarily locked")
371+ else if ((tryGetInteger("global_artAmount") >= artefactsLimit))
372+ then throw("SOLDOUT!!! Hurray!")
373+ else if (if ((1639605600000 > lastBlock.timestamp))
374+ then (i.caller != Address(devAddress))
375+ else false)
376+ then throw("Too early...")
377+ else {
378+ let firstPayment = value(i.payments[0])
379+ if ((firstPayment.assetId != getEggAssetId()))
380+ then throw(("You can attach only EGG tokens with the following asset id: " + toBase58String(getEggAssetId())))
381+ else if ((eggsNeeded > firstPayment.amount))
382+ then throw(("To hatch a duck you currently need the following amount of EGGlets: " + toString(eggsNeeded)))
383+ else [StringEntry((((toString(i.caller) + "_") + toBase58String(i.transactionId)) + "_status"), "started"), IntegerEntry((((toString(i.caller) + "_") + toBase58String(i.transactionId)) + "_finishHeight"), (height + 2)), IntegerEntry("global_artAmount", (tryGetInteger("global_artAmount") + 1))]
384+ }
385+
386+
387+
388+@Callable(i)
389+func setGlobalArtAmount (newAmount) = if (if ((i.caller == this))
390+ then true
391+ else (i.caller == Address(devAddress)))
392+ then [IntegerEntry("global_artAmount", newAmount)]
393+ else throw("Permission denied")
394+
395+
396+
397+@Callable(i)
398+func claimArtefact (boxIdStr) = {
399+ let txId = fromBase58String(boxIdStr)
400+ let statusKey = (((toString(i.caller) + "_") + boxIdStr) + "_status")
401+ let heightKey = (((toString(i.caller) + "_") + boxIdStr) + "_finishHeight")
402+ if ((getStringValue(statusKey) != "started"))
403+ then throw("claimed already")
404+ else if ((getIntegerValue(heightKey) > height))
405+ then throw("you cannot claim yet")
406+ else {
407+ let artType = getRandomArtefact(txId, getIntegerValue(heightKey))
408+ let asset = Issue(artType, "Artefact of Waves Ducks metaverse.", 1, 0, false, unit, getIntegerValue(heightKey))
409+ let assetId = calculateAssetId(asset)
410+[StringEntry(statusKey, artType), StringEntry((((toString(i.caller) + "_") + boxIdStr) + "_artefactId"), toBase58String(assetId)), StringEntry((toBase58String(assetId) + "_type"), artType), asset, ScriptTransfer(i.caller, 1, assetId)]
411+ }
412+ }
413+
414+
415+@Verifier(tx)
416+func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
362417
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let perchPrice = (100 * 1000000)
4+func keyArtefactOwner (artefactName,owner) = (((artefactName + "_") + owner) + "_owner")
55
6-let scale = 10000
76
8-let scale2 = 1000000
7+func keyUnstakeHeight (artefactName,artefactId) = (((artefactName + "_") + artefactId) + "_unstake_height")
8+
9+
10+func getProcessFinishHeightKey (address,txId) = (((address + "_") + toBase58String(txId)) + "_fh")
11+
12+
13+let devAddress = base58'3P44yqcpfhPF2iC1nptm2ZJCTaN7VYhz9og'
14+
15+let eggsNeeded = (3 * 100000000)
16+
17+let artefactsLimit = (301 + 600)
18+
19+let freeGenes = ["A", "B", "C", "D", "E"]
20+
21+let oldArtefacts = ["ART-LAKE", "ART-HOUSE", "ART-BIGHOUSE", "ART-FIXGENE", "ART-FREEGENE", "ART-MIRROR", "ART-POMP", "ART-CAPE", "ART-HAT", "ART-CUSTOMDUCK"]
22+
23+let artefacts = ["ART-XMISTL", "ART-XHAT", "ART-XSCARF", "ART-XSWEATER", "ART-XSOCK", "ART-XTREE"]
24+
25+let stakeableWithLock = ["ART-LAKE", "ART-XTREE"]
26+
27+let stakeableWithoutLock = ["ART-XMISTL"]
28+
29+let allStakeable = (stakeableWithoutLock ++ stakeableWithLock)
30+
31+let allArtefact = (artefacts ++ oldArtefacts)
32+
33+func tryGetString (key) = match getString(this, key) {
34+ case a: String =>
35+ a
36+ case _ =>
37+ ""
38+}
39+
40+
41+func tryGetInteger (key) = match getInteger(this, key) {
42+ case a: Int =>
43+ a
44+ case _ =>
45+ 0
46+}
47+
48+
49+func getRandomNumber (variants,txId,finishHeight,offset) = {
50+ let randomSeedBlock = value(blockInfoByHeight((finishHeight - 1)))
51+ let randomHash = sha256(((base58'items' + txId) + value(randomSeedBlock.vrf)))
52+ (toInt(randomHash, offset) % variants)
53+ }
54+
55+
56+func getRandomArtefact (boxId,h) = {
57+ let randomNumber = getRandomNumber(6, boxId, h, 1)
58+artefacts[randomNumber]
59+ }
60+
61+
62+func getRandomGenes (txId,h) = {
63+ let randomNumber = getRandomNumber(6, txId, h, 2)
64+freeGenes[randomNumber]
65+ }
66+
67+
68+func checkArtefactDetails (assetId) = {
69+ let asset = value(assetInfo(assetId))
70+ let assetName = value(asset.name)
71+ if (if (containsElement(allArtefact, assetName))
72+ then (asset.issuer == this)
73+ else false)
74+ then assetName
75+ else throw("Invalid artefact")
76+ }
77+
978
1079 func tryGetStringExternal (address,key) = match getString(address, key) {
1180 case a: String =>
1281 a
1382 case _ =>
1483 ""
1584 }
1685
1786
18-func tryGetString (key) = tryGetStringExternal(this, key)
19-
20-
2187 func getOracle () = Address(fromBase58String(tryGetString("static_oracleAddress")))
22-
23-
24-func getEggAssetId () = fromBase58String(tryGetStringExternal(getOracle(), "static_eggAssetId"))
25-
26-
27-func getIncubatorAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_incubatorAddress")))
28-
29-
30-func getRebirthAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_rebirthAddress")))
31-
32-
33-func getSwopPromoAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_swopPromoAddress")))
3488
3589
3690 func getBreederAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_breederAddress")))
3791
3892
39-func getRefContractAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_refContractAddress")))
40-
41-
42-func getItemsAddress () = Address(fromBase58String(tryGetStringExternal(getOracle(), "static_itemsAddress")))
43-
44-
45-let RefererReward = 5
46-
47-func getRewardPerBlock () = 684
48-
49-
50-func isLocked () = {
51- let masterAddress = Address(base58'3PEPftf2kWZDmAaWBjs6BUJa9957kiA2PkU')
52- match getInteger(masterAddress, "egglock") {
53- case b: Int =>
54- b
55- case _ =>
56- 0
57- }
58- }
59-
60-
61-func tryGetInteger (key) = match getInteger(this, key) {
62- case b: Int =>
63- b
64- case _ =>
65- 0
66-}
67-
68-
69-func isUserBlacklisted (address) = false
70-
71-
72-func getAssetOrigin (generation) = if ((generation == "G"))
73- then getIncubatorAddress()
74- else getBreederAddress()
75-
76-
77-func getAssetRarity (genotype,generation) = {
78- let quantity = valueOrErrorMessage(getInteger(getAssetOrigin(generation), (("stats_" + genotype) + "_quantity")), (("stats_" + genotype) + "_quantity not found"))
79- let power = pow((10000 / quantity), 4, 5, 1, 2, FLOOR)
80- if ((power > 0))
81- then power
82- else 2
83- }
93+func getEggAssetId () = fromBase58String(tryGetStringExternal(getOracle(), "static_eggAssetId"))
8494
8595
8696 func asString (value) = match value {
8797 case string: String =>
8898 string
8999 case _ =>
90100 throw("wrong type, expected: String")
91101 }
92102
93103
94104 func asInt (value) = match value {
95105 case int: Int =>
96106 int
97107 case _ =>
98108 throw("wrong type, expected: Int")
99109 }
100110
101111
102-func getAssetFarmingPower (assetId,address) = if (if ((value(assetInfo(assetId)).issuer == getBreederAddress()))
103- then true
104- else (value(assetInfo(assetId)).issuer == getIncubatorAddress()))
105- then {
106- let assetName = value(assetInfo(assetId)).name
107- let generation = take(takeRight(assetName, 2), 1)
108- let farmGen = asString(invoke(getBreederAddress(), "getGenFromName", [assetName], nil))
109- if ((farmGen == farmGen))
110- then {
111- let farmBoost = asInt(invoke(getItemsAddress(), "calculateFarmingPowerBoost", [toBase58String(assetId), address], nil))
112- if ((farmBoost == farmBoost))
113- then {
114- let rarity = getAssetRarity(farmGen, generation)
115- let totalFarmingPower = (rarity + fraction(rarity, farmBoost, 100))
116- $Tuple2(farmGen, totalFarmingPower)
117- }
118- else throw("Strict value is not equal to itself.")
119- }
120- else throw("Strict value is not equal to itself.")
121- }
122- else throw("not valid NFT")
112+func manipulateName (assetName,position,char) = ((take(assetName, (position - 1)) + char) + takeRight(assetName, (16 - position)))
123113
124114
125-func getLastKnownAssetFarmingPower (address,assetId) = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_farmingPower"))
126-
127-
128-func getAssetsByGen (gen) = {
129- let s = tryGetString(("assets_" + gen))
130- if ((s == ""))
131- then nil
132- else split(s, ",")
133- }
134-
135-
136-func calcInterest (previousInterest,previousInterestHeight,totalFarmingPower) = (previousInterest + (((scale * getRewardPerBlock()) * (height - previousInterestHeight)) / totalFarmingPower))
137-
138-
139-func getCurrentInterest () = if ((tryGetInteger("total_farmingPower") > 0))
140- then {
141- let previousInterest = tryGetInteger("total_lastCheckInterest")
142- let previousInterestHeight = tryGetInteger("total_lastCheckInterestHeight")
143- let totalFarmingPower = tryGetInteger("total_farmingPower")
144- calcInterest(previousInterest, previousInterestHeight, totalFarmingPower)
145- }
146- else if ((tryGetInteger("total_startHeight") != 0))
147- then tryGetInteger("total_lastCheckInterest")
148- else throw("farming is not launched, yet")
149-
150-
151-func calcAssetRewardDelta (address,assetId,assetFarmingPower) = {
152- let lastCheckAssetInterest = tryGetInteger((((("address_" + address) + "_asset_") + assetId) + "_lastCheckInterest"))
153- let currentInterest = getCurrentInterest()
154- (assetFarmingPower * (currentInterest - lastCheckAssetInterest))
155- }
156-
157-
158-func addAssetIdToGenEntry (assetId,assetGen) = {
159- let currentValue = tryGetString((("assets_" + assetGen) + "_locked"))
160- if ((currentValue == ""))
161- then assetId
162- else ((currentValue + ",") + assetId)
163- }
164-
165-
166-func getStakeResult (address,assetId,assetFarmingPower) = {
167- let asset = toBase58String(assetId)
168-[IntegerEntry("total_farmingPower", (tryGetInteger("total_farmingPower") + assetFarmingPower)), IntegerEntry("total_lastCheckInterest", getCurrentInterest()), IntegerEntry("total_lastCheckInterestHeight", height), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_farmingPower"), assetFarmingPower), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest"), getCurrentInterest())]
169- }
170-
171-
172-func getUnstakeResult (address,assetId,rewardDelta,withdrawnAmount,assetFarmingPower) = {
173- let asset = toBase58String(assetId)
174-[IntegerEntry("total_farmingPower", (tryGetInteger("total_farmingPower") - assetFarmingPower)), IntegerEntry("total_lastCheckInterest", getCurrentInterest()), IntegerEntry("total_lastCheckInterestHeight", height), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_farmingPower"), 0), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckInterest"), getCurrentInterest()), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount")) + (withdrawnAmount * scale2))), IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")) + rewardDelta))]
175- }
176-
177-
178-func calculatePerchPrice (address) = {
179- let hasArtefactStaked = tryGetStringExternal(getItemsAddress(), (("ART-XMISTL_" + address) + "_owner"))
180- if ((hasArtefactStaked == ""))
181- then perchPrice
182- else ((perchPrice / 10) * 9)
115+func itemIsInCoolDown (artefactName,artefactId) = {
116+ let unstakeHeightLast = tryGetInteger(keyUnstakeHeight(artefactName, artefactId))
117+ let cooldownPeriod = 240
118+ if ((height > (unstakeHeightLast + cooldownPeriod)))
119+ then false
120+ else true
183121 }
184122
185123
186124 @Callable(i)
187125 func configureOracle (oracle) = if ((i.caller != this))
188126 then throw("admin only")
189127 else [StringEntry("static_oracleAddress", oracle)]
190128
191129
192130
193131 @Callable(i)
194-func init () = if ((i.caller != this))
195- then throw("admin only")
196- else [IntegerEntry("total_startHeight", height)]
132+func calculateFarmingPowerBoost (duckId,address) = {
133+ let lakeBoost = if ((tryGetString(keyArtefactOwner("ART-LAKE", address)) != ""))
134+ then 2
135+ else 0
136+ let xmasTreeBoost = if ((tryGetString(keyArtefactOwner("ART-XTREE", address)) != ""))
137+ then 3
138+ else 0
139+ let totalBoost = (lakeBoost + xmasTreeBoost)
140+ $Tuple2(nil, totalBoost)
141+ }
197142
198143
199144
200145 @Callable(i)
201-func buyPerch (color,refererAddress) = if ((isLocked() > 0))
202- then throw("EGG operations are temporarily locked")
203- else if ((0 > value(indexOf(["B", "R", "G", "Y"], color))))
204- then throw("you need to set color properly")
146+func fixedGene (txIdStr,parentFixedGene,positionFixedGene) = {
147+ let firstPayment = value(i.payments[0])
148+ let firstAssetId = toBase58String(value(firstPayment.assetId))
149+ if ((firstPayment.amount != 1))
150+ then throw("NFT is not attached")
205151 else {
206- let firstPayment = value(i.payments[0])
207- let exactPrice = calculatePerchPrice(toString(i.caller))
208- if ((firstPayment.assetId != getEggAssetId()))
209- then throw(("You can attach only EGG tokens with the following asset id: " + toBase58String(getEggAssetId())))
210- else if ((firstPayment.amount != exactPrice))
211- then throw(("To buy a perch you currently need the following amount of EGGlets: " + toString(exactPrice)))
212- else {
213- let refererRewardForPerch = fraction(firstPayment.amount, RefererReward, 100)
214- let refCall = invoke(getRefContractAddress(), "refPayment", [refererAddress], [AttachedPayment(getEggAssetId(), refererRewardForPerch)])
215- if ((refCall == refCall))
216- then {
217- let perchAmountKey = ((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)
218- let perchAmount = tryGetInteger(perchAmountKey)
219-[IntegerEntry(perchAmountKey, (perchAmount + 1))]
220- }
221- else throw("Strict value is not equal to itself.")
222- }
152+ let artefact = checkArtefactDetails(value(firstPayment.assetId))
153+ if ((artefact != "ART-FIXGENE"))
154+ then throw("You need to attach a ART-FIXGENE artefact")
155+ else {
156+ let txId = fromBase58String(txIdStr)
157+ let finishHeightKey = getProcessFinishHeightKey(toString(i.caller), txId)
158+ let processFinishHeight = getIntegerValue(getBreederAddress(), finishHeightKey)
159+ let duckGenesString = asString(invoke(getBreederAddress(), "generateDuck", [txIdStr, processFinishHeight, parentFixedGene, positionFixedGene, "", 0], nil))
160+ if ((duckGenesString == duckGenesString))
161+ then {
162+ let call = invoke(getBreederAddress(), "finishDuckHatchingItems", [txIdStr, duckGenesString], nil)
163+ if ((call == call))
164+ then [Burn(value(firstPayment.assetId), 1)]
165+ else throw("Strict value is not equal to itself.")
166+ }
167+ else throw("Strict value is not equal to itself.")
168+ }
223169 }
170+ }
224171
225172
226173
227174 @Callable(i)
228-func addFreePerch (address,color) = if ((0 > value(indexOf(["B", "R", "G", "Y"], color))))
229- then throw("you need to set color properly")
230- else if (if (if ((i.caller != getRebirthAddress()))
231- then (i.caller != this)
232- else false)
233- then (i.caller != getSwopPromoAddress())
234- else false)
235- then throw("rebirth and swop promo only")
175+func freeGene (txIdStr) = {
176+ let firstPayment = value(i.payments[0])
177+ let firstAssetId = toBase58String(value(firstPayment.assetId))
178+ if ((firstPayment.amount != 1))
179+ then throw("NFT is not attached")
236180 else {
237- let perchAmountKey = ((("address_" + address) + "_perchesAvailable_") + color)
238- let perchAmount = tryGetInteger(perchAmountKey)
239- $Tuple2([IntegerEntry(perchAmountKey, (perchAmount + 1))], "")
181+ let artefact = checkArtefactDetails(value(firstPayment.assetId))
182+ if ((artefact != "ART-FREEGENE"))
183+ then throw("You need to attach a ART-FREEGENE artefact")
184+ else {
185+ let txId = fromBase58String(txIdStr)
186+ let finishHeightKey = getProcessFinishHeightKey(toString(i.caller), txId)
187+ let processFinishHeight = getIntegerValue(getBreederAddress(), finishHeightKey)
188+ let selectedGene = getRandomGenes(txId, processFinishHeight)
189+ let randomPosition = getRandomNumber(7, txId, processFinishHeight, 3)
190+ let duckGenesString = asString(invoke(getBreederAddress(), "generateDuck", [txIdStr, processFinishHeight, 0, 0, selectedGene, randomPosition], nil))
191+ if ((duckGenesString == duckGenesString))
192+ then {
193+ let call = invoke(getBreederAddress(), "finishDuckHatchingItems", [txIdStr, duckGenesString], nil)
194+ if ((call == call))
195+ then [Burn(value(firstPayment.assetId), 1)]
196+ else throw("Strict value is not equal to itself.")
197+ }
198+ else throw("Strict value is not equal to itself.")
199+ }
240200 }
201+ }
241202
242203
243204
244205 @Callable(i)
245-func stakeNFT () = if ((isLocked() > 0))
246- then throw("EGG operations are temporarily locked")
247- else {
248- let pmt = value(i.payments[0])
249- let assetId = value(value(i.payments[0]).assetId)
250- let address = toString(i.caller)
251- let color = takeRight(value(assetInfo(assetId)).name, 1)
252- let availablePerches = tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color))
253- if ((pmt.amount != 1))
206+func copyDuck () = {
207+ let firstPayment = value(i.payments[0])
208+ let secondPayment = value(i.payments[1])
209+ let firstAssetId = toBase58String(value(firstPayment.assetId))
210+ let children = asInt(invoke(getBreederAddress(), "validateAndGetChildren", [firstAssetId], nil))
211+ if ((children == children))
212+ then if (if ((firstPayment.amount != 1))
213+ then true
214+ else (secondPayment.amount != 1))
254215 then throw("NFT is not attached")
255- else if ((0 >= availablePerches))
256- then throw(("no perches available for the color " + color))
257- else {
258- let $t096749747 = getAssetFarmingPower(assetId, address)
259- let assetGen = $t096749747._1
260- let assetFarmingPower = $t096749747._2
261- let assetRewardDelta = calcAssetRewardDelta(address, toBase58String(assetId), assetFarmingPower)
262- (getStakeResult(address, assetId, assetFarmingPower) ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (availablePerches - 1))])
263- }
264- }
216+ else {
217+ let artefact = checkArtefactDetails(value(secondPayment.assetId))
218+ if ((artefact != "ART-MIRROR"))
219+ then throw("You need to attach a ART-MIRROR artefact")
220+ else {
221+ let nftInfo = value(assetInfo(value(firstPayment.assetId)))
222+ let asset1Gen = split(nftInfo.name, "")
223+ if (if ((asset1Gen[14] == "G"))
224+ then true
225+ else (asset1Gen[14] == "J"))
226+ then throw("You can't mirror this duck")
227+ else {
228+ let duckGen = nftInfo.name
229+ let call = invoke(getBreederAddress(), "createDuckSpecialGenes", [i.caller.bytes, duckGen, children], nil)
230+ if ((call == call))
231+ then [ScriptTransfer(i.caller, 1, firstPayment.assetId), Burn(value(secondPayment.assetId), 1)]
232+ else throw("Strict value is not equal to itself.")
233+ }
234+ }
235+ }
236+ else throw("Strict value is not equal to itself.")
237+ }
265238
266239
267240
268241 @Callable(i)
269-func unstakeNFT (asset) = if (isUserBlacklisted(toString(i.caller)))
270- then throw("Ooops, looks like you lost in one of the Ducksquid games! As you already know, any loss has its consequences, so you will be not able to claim your farming rewards till the end of DuckSquid game. Quack in peace!")
271- else if ((isLocked() > 0))
272- then throw("EGG operations are temporarily locked")
242+func addArteFactToDuck () = {
243+ let firstPayment = value(i.payments[0])
244+ let secondPayment = value(i.payments[1])
245+ let firstAssetId = toBase58String(value(firstPayment.assetId))
246+ if (if ((firstPayment.amount != 1))
247+ then true
248+ else (secondPayment.amount != 1))
249+ then throw("NFT is not attached")
273250 else {
274- let assetId = fromBase58String(asset)
275- let address = toString(i.caller)
276- let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
277- let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
278- let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
279- let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
280- let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
281- let color = takeRight(value(assetInfo(assetId)).name, 1)
282- if ((0 >= assetFarmingPower))
283- then throw("asset not available")
284- else if ((color == "U"))
285- then throw("use another function to unstake Jackpot NFT")
251+ let children = asInt(invoke(getBreederAddress(), "validateAndGetChildren", [firstAssetId], nil))
252+ if ((children == children))
253+ then if ((children == 0))
254+ then throw("You can only pick a sterile NFT-duck")
286255 else {
287- let result = getUnstakeResult(address, assetId, assetRewardDelta, reward, assetFarmingPower)
288- $Tuple2((result ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)) + 1)), ScriptTransfer(i.caller, (reward * 1000000), getEggAssetId()), ScriptTransfer(i.caller, 1, assetId)]), (reward * 1000000))
256+ let artefact = checkArtefactDetails(value(secondPayment.assetId))
257+ if (if ((artefact != "ART-XHAT"))
258+ then (artefact != "ART-POMP")
259+ else false)
260+ then throw("You need to attach a ART-XHAT or ART-POMP artefact")
261+ else {
262+ let nftInfo = value(assetInfo(value(firstPayment.assetId)))
263+ let asset1Gen = split(nftInfo.name, "")
264+ if (if ((asset1Gen[14] == "G"))
265+ then true
266+ else (asset1Gen[14] == "J"))
267+ then throw("You can't mirror this duck")
268+ else if (if ((asset1Gen[5] == "S"))
269+ then true
270+ else (asset1Gen[5] == "T"))
271+ then throw("you already attached a artefact")
272+ else {
273+ let char = if ((artefact == "ART-XHAT"))
274+ then "T"
275+ else if ((artefact == "ART-POMP"))
276+ then "S"
277+ else throw("No char defined")
278+ let oldDuckGen = nftInfo.name
279+ let oldFarmGen = asString(invoke(getBreederAddress(), "getGenFromName", [oldDuckGen], nil))
280+ if ((oldFarmGen == oldFarmGen))
281+ then {
282+ let duckGen = manipulateName(oldDuckGen, 6, char)
283+ let call = invoke(getBreederAddress(), "createDuckSpecialGenes", [i.caller.bytes, duckGen, children], nil)
284+ if ((call == call))
285+ then {
286+ let callReduce = invoke(getBreederAddress(), "reduceRarity", [firstAssetId, oldFarmGen], nil)
287+ if ((callReduce == callReduce))
288+ then [Burn(value(firstPayment.assetId), 1), Burn(value(secondPayment.assetId), 1)]
289+ else throw("Strict value is not equal to itself.")
290+ }
291+ else throw("Strict value is not equal to itself.")
292+ }
293+ else throw("Strict value is not equal to itself.")
294+ }
295+ }
289296 }
297+ else throw("Strict value is not equal to itself.")
290298 }
299+ }
291300
292301
293302
294303 @Callable(i)
295-func stakeJackpot (color) = if ((isLocked() > 0))
296- then throw("EGG operations are temporarily locked")
297- else {
298- let pmt = value(i.payments[0])
299- let assetId = value(pmt.assetId)
300- let address = toString(i.caller)
301- let availablePerches = tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color))
302- let assetIssuer = value(assetInfo(assetId)).issuer
303- if ((pmt.amount != 1))
304- then throw("NFT is not attached")
305- else if (if ((assetIssuer == getIncubatorAddress()))
306- then true
307- else (assetIssuer == getBreederAddress()))
308- then if ((takeRight(value(value(assetInfo(assetId)).name), 1) != "U"))
309- then throw("jackpot only")
310- else if ((0 >= availablePerches))
311- then throw(("no perches available for the color " + color))
312- else (getStakeResult(address, assetId, 100) ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (availablePerches - 1)), StringEntry((((("address_" + toString(i.caller)) + "_asset_") + toBase58String(assetId)) + "_perchColor"), color)])
313- else throw("asset is not valid")
304+func stakeItem () = if (if ((size(i.payments) == 1))
305+ then (i.payments[0].amount == 1)
306+ else false)
307+ then {
308+ let assetId = value(i.payments[0].assetId)
309+ let artefactName = checkArtefactDetails(assetId)
310+ if (containsElement(allStakeable, artefactName))
311+ then if (if (containsElement(stakeableWithLock, artefactName))
312+ then itemIsInCoolDown(artefactName, toBase58String(assetId))
313+ else false)
314+ then throw("Item can't be staked yet, it's in cooldown")
315+ else {
316+ let invoker = toString(i.caller)
317+ let artefactId = tryGetString(keyArtefactOwner(artefactName, invoker))
318+ if ((artefactId == ""))
319+ then [StringEntry(keyArtefactOwner(artefactName, invoker), toBase58String(assetId))]
320+ else throw(("You are already staking " + artefactName))
321+ }
322+ else throw("You can't stake this artafect")
314323 }
324+ else throw("Invalid payment")
315325
316326
317327
318328 @Callable(i)
319-func unstakeJackpot (asset) = if (isUserBlacklisted(toString(i.caller)))
320- then throw("Ooops, looks like you lost in one of the Ducksquid games! As you already know, any loss has its consequences, so you will be not able to claim your farming rewards till the end of DuckSquid game. Quack in peace!")
321- else if ((isLocked() > 0))
322- then throw("EGG operations are temporarily locked")
323- else {
324- let assetId = fromBase58String(asset)
325- let address = toString(i.caller)
326- let color = tryGetString((((("address_" + address) + "_asset_") + asset) + "_perchColor"))
327- let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
328- let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
329- let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
330- let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
331- let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
332- if ((takeRight(value(value(assetInfo(assetId)).name), 1) != "U"))
333- then throw("jackpot only")
334- else if ((assetFarmingPower > 0))
335- then {
336- let result = getUnstakeResult(address, assetId, assetRewardDelta, reward, assetFarmingPower)
337- $Tuple2((result ++ [IntegerEntry(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color), (tryGetInteger(((("address_" + toString(i.caller)) + "_perchesAvailable_") + color)) + 1)), ScriptTransfer(i.caller, (reward * 1000000), getEggAssetId()), ScriptTransfer(i.caller, 1, assetId)]), (reward * 1000000))
338- }
339- else throw("")
340- }
329+func unstakeItem (artefactName) = if (containsElement(allArtefact, artefactName))
330+ then {
331+ let invoker = toString(i.caller)
332+ let artefactId = tryGetString(keyArtefactOwner(artefactName, invoker))
333+ if ((artefactId == ""))
334+ then throw(("You didnt stake " + artefactName))
335+ else [IntegerEntry(keyUnstakeHeight(artefactName, artefactId), height), ScriptTransfer(i.caller, 1, fromBase58String(artefactId)), DeleteEntry(keyArtefactOwner(artefactName, invoker))]
336+ }
337+ else throw("This artefact doesn't exist")
341338
342339
343340
344341 @Callable(i)
345-func claimReward (asset) = if (isUserBlacklisted(toString(i.caller)))
346- then throw("Ooops, looks like you lost in one of the Ducksquid games! As you already know, any loss has its consequences, so you will be not able to claim your farming rewards till the end of DuckSquid game. Quack in peace!")
347- else if ((isLocked() > 0))
348- then throw("EGG operations are temporarily locked")
349- else {
350- let address = toString(i.caller)
351- let assetId = fromBase58String(asset)
352- let assetFarmingPower = getLastKnownAssetFarmingPower(address, asset)
353- let assetRewardDelta = calcAssetRewardDelta(address, asset, assetFarmingPower)
354- let farmedAmount = (assetRewardDelta + tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_lastCheckFarmedAmount")))
355- let withdrawnAmount = tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"))
356- let reward = ((farmedAmount - withdrawnAmount) / (scale * 100))
357- if ((0 >= reward))
358- then throw("you have no EGGs to withdraw")
359- else $Tuple2([IntegerEntry((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount"), (tryGetInteger((((("address_" + address) + "_asset_") + asset) + "_withdrawnAmount")) + (reward * scale2))), ScriptTransfer(Address(fromBase58String(address)), (reward * 1000000), getEggAssetId())], (reward * 1000000))
360- }
342+func preInit () = [IntegerEntry("static_ART-LAKE_farmingSlots", 200), IntegerEntry("static_ART-LAKE_farmingBoost", 2), IntegerEntry("static_ART-HOUSE_farmingSlots", 4), IntegerEntry("static_ART-HOUSE_farmingBoost", 30), IntegerEntry("static_ART-BIGHOUSE_farmingSlots", 10), IntegerEntry("static_ART-BIGHOUSE_farmingBoost", 15)]
361343
344+
345+
346+@Callable(i)
347+func issueArtefact (type,receiver) = if ((i.caller == this))
348+ then {
349+ let txIdStr = toBase58String(i.transactionId)
350+ let address = Address(fromBase58String(receiver))
351+ let artefact = Issue(type, "NFT artefact of Waves Ducks game. Drop #2.", 1, 0, false, unit, 0)
352+ let artefactId = calculateAssetId(artefact)
353+[artefact, StringEntry((("artefact_" + toBase58String(artefactId)) + "_type"), type), ScriptTransfer(address, 1, artefactId)]
354+ }
355+ else throw("admin only")
356+
357+
358+
359+@Callable(i)
360+func setLock (n) = if ((i.caller == this))
361+ then [IntegerEntry("global_locked", n)]
362+ else throw("admin only")
363+
364+
365+
366+@Callable(i)
367+func buyArtefact () = if ((lastBlock.timestamp > 1639742400000))
368+ then throw("There are no active sales now... ")
369+ else if ((tryGetInteger("global_locked") > 0))
370+ then throw("contract is temporarily locked")
371+ else if ((tryGetInteger("global_artAmount") >= artefactsLimit))
372+ then throw("SOLDOUT!!! Hurray!")
373+ else if (if ((1639605600000 > lastBlock.timestamp))
374+ then (i.caller != Address(devAddress))
375+ else false)
376+ then throw("Too early...")
377+ else {
378+ let firstPayment = value(i.payments[0])
379+ if ((firstPayment.assetId != getEggAssetId()))
380+ then throw(("You can attach only EGG tokens with the following asset id: " + toBase58String(getEggAssetId())))
381+ else if ((eggsNeeded > firstPayment.amount))
382+ then throw(("To hatch a duck you currently need the following amount of EGGlets: " + toString(eggsNeeded)))
383+ else [StringEntry((((toString(i.caller) + "_") + toBase58String(i.transactionId)) + "_status"), "started"), IntegerEntry((((toString(i.caller) + "_") + toBase58String(i.transactionId)) + "_finishHeight"), (height + 2)), IntegerEntry("global_artAmount", (tryGetInteger("global_artAmount") + 1))]
384+ }
385+
386+
387+
388+@Callable(i)
389+func setGlobalArtAmount (newAmount) = if (if ((i.caller == this))
390+ then true
391+ else (i.caller == Address(devAddress)))
392+ then [IntegerEntry("global_artAmount", newAmount)]
393+ else throw("Permission denied")
394+
395+
396+
397+@Callable(i)
398+func claimArtefact (boxIdStr) = {
399+ let txId = fromBase58String(boxIdStr)
400+ let statusKey = (((toString(i.caller) + "_") + boxIdStr) + "_status")
401+ let heightKey = (((toString(i.caller) + "_") + boxIdStr) + "_finishHeight")
402+ if ((getStringValue(statusKey) != "started"))
403+ then throw("claimed already")
404+ else if ((getIntegerValue(heightKey) > height))
405+ then throw("you cannot claim yet")
406+ else {
407+ let artType = getRandomArtefact(txId, getIntegerValue(heightKey))
408+ let asset = Issue(artType, "Artefact of Waves Ducks metaverse.", 1, 0, false, unit, getIntegerValue(heightKey))
409+ let assetId = calculateAssetId(asset)
410+[StringEntry(statusKey, artType), StringEntry((((toString(i.caller) + "_") + boxIdStr) + "_artefactId"), toBase58String(assetId)), StringEntry((toBase58String(assetId) + "_type"), artType), asset, ScriptTransfer(i.caller, 1, assetId)]
411+ }
412+ }
413+
414+
415+@Verifier(tx)
416+func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
362417

github/deemru/w8io/3ef1775 
89.01 ms