diff --git a/api/data/interfaces.ts b/api/data/interfaces.ts index e0197bf..f4e5690 100644 --- a/api/data/interfaces.ts +++ b/api/data/interfaces.ts @@ -7,6 +7,7 @@ export interface BalanceV3 { export interface ClaimingBalance extends BalanceV3 { dmdv4Address: string; signature: string; + postfix?: string; } export interface ClaimingDataSet { diff --git a/hardhat.config.ts b/hardhat.config.ts index 962b417..da669fa 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -44,6 +44,18 @@ const config: HardhatUserConfig = { mnemonic }, + allowUnlimitedContractSize: true, + hardfork: "istanbul", + minGasPrice: 1000000000 + }, + alpha4: { + url: "http://62.171.133.46:54100", + accounts: { + count: 10, + path: "m/44'/60'/0'/0", + mnemonic + }, + allowUnlimitedContractSize: true, hardfork: "istanbul", minGasPrice: 1000000000 @@ -90,6 +102,14 @@ const config: HardhatUserConfig = { browserURL: "http://62.171.133.46:4000", }, }, + { + network: "alpha4", + chainId: 777018, + urls: { + apiURL: "http://62.171.133.46:4400/api", + browserURL: "http://62.171.133.46:4400", + }, + }, ], }, mocha: { diff --git a/package.json b/package.json index 10a1bc1..3a2b264 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "test-deploy-and-fill": "ts-node scripts/test-fill.ts", "test-claim": "ts-node scripts/test-claim.ts", "fill-alpha3": "ts-node scripts/fill-alpha3.ts", + "fill-alpha4": "ts-node scripts/fill-alpha4.ts", "solhint": "solhint 'contracts/**/*.sol'" }, "repository": { diff --git a/scripts/fill-alpha4.ts b/scripts/fill-alpha4.ts new file mode 100644 index 0000000..97a55ec --- /dev/null +++ b/scripts/fill-alpha4.ts @@ -0,0 +1,145 @@ +import hre from "hardhat"; +import { CryptoSol } from "../api/src/cryptoSol"; +import { ClaimContract, ClaimContract__factory } from "../typechain-types"; +import { stringToUTF8Hex } from "../api/src/cryptoHelpers"; +import { BalanceV3 } from "../api/data/interfaces"; + +let ethers = hre.ethers; + + +//const prefix = "TESTNET dmd v4 coins are voluntary distributed towards DMD v3 snapshot coin balance owners based on the ruleset described in the open source contracts and whitepaper by using the claiming dapp u agree to this rulesets. target dmd v4 claiming address: "; +// const prefix = ""; +const prefix = "claim alpha4 to: "; + + +async function main() { + + let claimBeneficorAddress = "0x2000000000000000000000000000000000000001"; + let beneficorDAOAddress = "0xDA0da0da0Da0Da0Da0DA00DA0da0da0DA0DA0dA0"; + + //let dillute1 = + let now = (Date.now() / 1000).toFixed(0); + + let signer = (await hre.ethers.getSigners())[0]; + + + + console.log("using signer:", signer.address); + const signerBalance = await ethers.provider.getBalance(signer.address); + console.log("balance:", signerBalance); + + if (signerBalance == BigInt(0)) { + console.error("No Balance for this signer"); + return; + } + + const hour = 60 * 60; + const day = hour * 24; + const dillute1 = now + 7 * day; + const dillute2 = dillute1 + 7 * day; + const dillute3 = dillute2 + 7 * day; + + const contractFactory = await ethers.getContractFactory("ClaimContract"); + + const prefixHex = stringToUTF8Hex(prefix); + console.log("prefixHex", prefixHex); + const claimContractAny : any = await contractFactory.deploy(claimBeneficorAddress, beneficorDAOAddress, prefixHex, dillute1, dillute2, dillute3); + const claimContract = claimContractAny as ClaimContract; + + await claimContract.waitForDeployment(); + let claimContractAddress = await claimContract.getAddress(); + console.log('claim contract deployed to:', claimContractAddress); + console.log(`trying to verify.`); + console.log(`npx command to verify localy - if the automated command fails:`); + console.log(`npx hardhat verify --network alpha4 ${claimContractAddress} ${claimBeneficorAddress} ${beneficorDAOAddress} ${prefixHex} ${dillute1} ${dillute2} ${dillute3}` ); + + + let cryptoSol = new CryptoSol(claimContract); + cryptoSol.setLogDebug(true); + // it doesnt need to be super accurate, we can work with floating point numbers here. + let allCoins = 3824716; + + //let allCoins = 1; + // - 75% early + // - 5% mid + // - 5% late + // - 15% never + + let totalEarly = allCoins * 0.75; + let totalMid = allCoins * 0.05; + let totalLate = allCoins * 0.05; + let totalNever = allCoins * 0.15; + + let earlyAccounts = [ + "dbnJAWXKYvmoqV5bonJdgY3yuzHgrdHJQs", + "dEaTZND5nXeZRZgJt1z6HVmP7mtZ3demQK", + "dEx99xwAmqZtZtL6VrtxNv5pH2dtk6kTMH", + "dc71fVvE17UEZEZb7qbQmaLWm3D15QkB4V", + "dTmpgqgC2qoc9bitKCdVMM19gyJNfMudBR", + "dFQHpmkSScf9WXcyzDWK25BM62N218ViS7", + "dJU7z5oXd5ZsXZybRWadHnUzFgCY5ukZU5", + "dYUyrALxXrzpwyE41cntKHgPS4BYSB3rQX", + "dY3DefvBW4ySwfqJdPUVrmMyqDVW6cPJbd", + "dQkNJHJtow742w1Pmm3txRJQ6xt9bQaxb7", + "dHN8MdcZQVedNp3xY5mFvr8gLDeRkxR116", + "dSKqzw53y8Jgk4Y82usx3PWGx38yScpm7T", + "dDrm7QnGkLubQyNtnbbg7ZvkTEfTwAFaoq", + "dQVvs2Kjnhijge1BvHmejhV6GJRsiw8DCc" + ]; + + // let unclaimed = [ + // "dEx99xwAmqZtZtL6VrtxNv5pH2dtk6kTMH", + // "dTmpgqgC2qoc9bitKCdVMM19gyJNfMudBR", + // "dFQHpmkSScf9WXcyzDWK25BM62N218ViS7", + // "dHN8MdcZQVedNp3xY5mFvr8gLDeRkxR116", + // "dSKqzw53y8Jgk4Y82usx3PWGx38yScpm7T", + // "dDrm7QnGkLubQyNtnbbg7ZvkTEfTwAFaoq", + // "dQVvs2Kjnhijge1BvHmejhV6GJRsiw8DCc" + // ]; + + + let toWeiString = (value: number) => { + + let num = value * Number(ethers.WeiPerEther); + console.log(num); + let big = BigInt(num); + console.log(big); + let result = ethers.formatUnits(big, 0); + console.log(result); + return result; + } + + let earlyBalances : BalanceV3[] = earlyAccounts.map((a) => { return {dmdv3Address: a, value: toWeiString(totalEarly / earlyAccounts.length) }; }); + + + // 0xbC81e4c79447F73022B02203b14a526f64B821E0 + let balances : BalanceV3[] = [ + // designed for early. + ...earlyBalances, + // designed for mid. + { dmdv3Address: "dNddYBwd1xeu2snmJt4YxMcG2qWChcHCNt", value: toWeiString(totalMid) }, + // designed for late. + { dmdv3Address: "dPmptc1PYyNn4kpMgqNz5S1Wj3JFEs6fqk", value: toWeiString(totalLate)}, + // designed for never. + { dmdv3Address: "dHRKrnhhtGTiNRrCpLkmvhUKUWNB247mah", value: toWeiString(totalNever)}, + ]; + + let sponsor = (await ethers.getSigners())[0]; + await cryptoSol.fillBalances(sponsor, balances); + + await hre.run("verify:verify", { + address: claimContractAddress, + constructorArguments: [ + claimBeneficorAddress, + beneficorDAOAddress, + prefixHex, + dillute1, + dillute2, + dillute3, + ], + }); +} + +main(); + + diff --git a/slither.sh b/slither.sh new file mode 100755 index 0000000..71947c6 --- /dev/null +++ b/slither.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +solc-select install 0.8.26 +solc-select use 0.8.26 + +slither contracts/*.sol \ No newline at end of file diff --git a/test/ClaimContract.spec.ts b/test/ClaimContract.spec.ts index c110638..d9ac774 100644 --- a/test/ClaimContract.spec.ts +++ b/test/ClaimContract.spec.ts @@ -329,7 +329,7 @@ describe('ClaimContract', () => { for (const balance of balances.balances) { let balanceBeforeClaim = await ethers.provider.getBalance(balance.dmdv4Address); - await cryptoSol.claim(balance.dmdv3Address, balance.dmdv4Address, balance.signature, ""); + await cryptoSol.claim(balance.dmdv3Address, balance.dmdv4Address, balance.signature, balance.postfix ?? ""); let balanceAfterClaim = await ethers.provider.getBalance(balance.dmdv4Address); let expectedBalance = ethers.toBigInt(balance.value) + balanceBeforeClaim; @@ -337,20 +337,6 @@ describe('ClaimContract', () => { } } - describe("cryptographics with defined message prefix", async function () { - const claimToString = stringToUTF8Hex('claim to '); - - async function deployWithPrefixFixture(): Promise<{ claimContract: ClaimContract }> { - const claimContract = await deployClaiming( - lateClaimBeneficorAddress, - lateClaimBeneficorDAO, - claimToString - ); - - return { claimContract }; - } - }); - describe("balance", async function () { it('fill() a balance testset', async () => { @@ -466,6 +452,14 @@ describe('ClaimContract', () => { await runAddAndClaimTests(getTestBalancesFromTestdata("known_y_00")); }); + it("Claiming DMD with postfixes", async () => { + await runAddAndClaimTests(getTestBalancesFromTestdata("with_postfixes")); + }); + + it("Claiming DMD with long prefix", async () => { + await runAddAndClaimTests(getTestBalancesFromTestdata("long_prefix")); + }); + if (runLargeTests) { it("Claiming DMD large test: balances_1k", async () => { await runAddAndClaimTests(getTestBalancesFromTestdata("balances_1k")); @@ -474,6 +468,7 @@ describe('ClaimContract', () => { it("Claiming DMD large test: balances_50k", async () => { await runAddAndClaimTests(getTestBalancesFromTestdata("balances_50k")); }).timeout(60_000 * 60); // maximum 1 hour for this test. + } }); diff --git a/test/testdata/long_prefix.json b/test/testdata/long_prefix.json new file mode 100644 index 0000000..ce4114a --- /dev/null +++ b/test/testdata/long_prefix.json @@ -0,0 +1,145 @@ +{ + "messagePrefix": "i want to claim to an addres, and my the configured claiming message has an incredible long prefix that needs to get testet as well in unit tests, so we know that even very long claiming message to not introduce problems, be it as part of the signing process with the old v3 wallet, or within the claiming contracts. this message should be long enough now to cover the planned message prefix on the final network, therefore i want to claim my coins to the address: ", + "balances": [ + { + "dmdv3Address": "dFuBsnp3j5r9h8EQUA7jCU7L5XCNGHK4H8", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "ICckxlJYpOujJ2KgcFjPhGDHocB18IGv5Wybhcl6YvHjZlOwGdibWjZXJCtCsc7Qew/r4BNAXLrU37cx7DNGEaM=", + "postfix": " -0" + }, + { + "dmdv3Address": "dcH1w66amSzQHpR7RTUTmH5xfNTf1zbZDn", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IFoOvJU5kQZbGHMnmLPNZJmYYvCrFT2j7Uyk93Mi+223azq/WiWXcsm5x9iv4asz5Z5tYHFh9k4WDqTeGXF/hS0=", + "postfix": " -1" + }, + { + "dmdv3Address": "dFcRF9avhHJJyP2L35XKjbi9mRp8sp72pW", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IIrSnEwj+Ni07CchctUVphDkApk83/qsZOYegI3WvsBWPGtoPRvz/Rnt1Ry6bwIcrlcIe+7IqSjetr3YxVRb9EE=", + "postfix": "" + }, + { + "dmdv3Address": "dUCT6Nt7LvcCW5LsCxe2ARfp5C7frduHPQ", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IEmJbkfdbrMP73dKnHf8mTWRjWAQ/HA20CW3lPuWF4N3P4rUx5D2jBacXL4PFCQF7WmzkWmwVxdR5hPwiOzA9sU=", + "postfix": " -3" + }, + { + "dmdv3Address": "dVnpCAhGfLeyG5ASRqoGJU6EDcKnBDtbWj", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "II/1Y7fVOzIUnLiVKVRZD1tCx1U0DOd+BtCrZ9wAlmxTWIZca4rqZTaMqzUNuJT/SxThUi2osE/53yf5v29bRO4=", + "postfix": " -4" + }, + { + "dmdv3Address": "dU7SVJ5GgSmKAmkojpvxYH9kSiE1psZEHT", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IOZl8j6F4MCY6RsHQebkwtfNt58eKC4IWzCMUfdCjVVFNo+ktE/GSFhK2l/xrwielEyMrB0tH8KUiUBBLZraCb4=", + "postfix": " -5" + }, + { + "dmdv3Address": "dJWZcMoEp9i8WQZbvQhUJ1aXCCsJgjDmgL", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IGuKwYHNHbJftvKls31Ibgv1p8MklRUy3a1EW446q271IvgijlptWiszNTYriprRmIoq7PnL/V0aKWi7V518k6Y=", + "postfix": " -6" + }, + { + "dmdv3Address": "daWNfrxCEwyyQymqh3xRrY5TfhWHZjvfDT", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IKO5brGXieBtdBg85gvVjNhpFG6VSWTtdN6lSboH9pScQrTCqzsf2d5Fe08zdDZGISjc88IIutNFME2dXL4WM/U=", + "postfix": "" + }, + { + "dmdv3Address": "dWkHc88d2EePHhDMAk5MnyEaRF47T13Yg1", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IDfNgmm1dXQiUC1RxEsVMfmatx0F7Ursh1Cl4WP5IyhHcTABcPi2+FlW926gmzFu7TkjW+zJtxg1MM2hA54kqAM=", + "postfix": "" + }, + { + "dmdv3Address": "dXUgueHvZfBmtobPED5y7jNbt6KuWGsGE8", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IGWyjCPu6wErwN2wYSkJ5ZSUQG++Kp+dXG2kTZlSy3JSYbGO0O2IayOv5LAByFLu759oi80v1VnWPzJl0Kz2sAg=", + "postfix": "" + }, + { + "dmdv3Address": "dLkqngo9YzVkJuqcJ1DkyCDZTjh2yXVS7N", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IH+h9RrIqhUOUojqIj0Z/UAanjX8mDG51WHOZ0bQRFWjS2h/hN2WAflygMtYk4SLyu0Xau36vW+Kuzf2xp6u2k8=", + "postfix": "" + }, + { + "dmdv3Address": "das98tqKdS9iEoEUj51XUSqGAVFAeT9EmX", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IDI7k16uc3/zo8QQgsLXNKB27PhJbQz2R3uXwk2xchyRPN5AkoltNnvs0gtuSByxiLglXVUSoLLAbkvb+zZd5Jw=", + "postfix": " -11" + }, + { + "dmdv3Address": "dDWsSowaJNCnsgC821uJYYhLtMvCUawM12", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IK4WmfxTrgGYLkKAVo7yMuObOULdmwSQsfqWG/yaOf1BUoN/4GgPLVZ1Xnc0nfLhmpVzegHsZZo+5GlLGt/4v8M=", + "postfix": "" + }, + { + "dmdv3Address": "dWrMwbHc2L7ba91huB5JPRUXEWz2MwrVNV", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IL6m16qb2xel+DJc0Fpta8/lf0Zz/EWmBX3mNALIwnPwBa/pl+YSDGcnMYjKvqYli43wTfn0tUgDq1aJ9SeTBiE=", + "postfix": " -13" + }, + { + "dmdv3Address": "dKd4xtMPRHxG7joeFaTgAWJFv7uzt8HUXP", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IN3W7KGVlAamSYmAV8FXXF8+OaTMmnau562UOMJlW8PBCHbcF2e3/E02CwPO6L8sINIEBzbTWbNGSbLxhJXxGPM=", + "postfix": " -14" + }, + { + "dmdv3Address": "dQ3tCrmqQhT7EGr8tGw9276Aioif24R44M", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IHOutk+37CZibxGq3BtNEsK65EUKRufDMbZSI8P4apchcT9wsXVIFnczwGYVZgTwFG2IvfL4qVjzWcDAJQZo9rk=", + "postfix": " -15" + }, + { + "dmdv3Address": "dWwUZRoJWeXDvpNrEE98wKm3dGPBv8Qhvd", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IAuHkPxkfvnP2Rssi+gHCxck6jlI8YCNbQCc/fPnQLSuFrSZLUI9S1U/n1XsjoDUjvZUngxiRC2XEPHw25dyI2E=", + "postfix": "" + }, + { + "dmdv3Address": "dEPsKw4wrgEsZEghmR2KNbpjEEAvEsYRvS", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IETjBllhKQzjjv6IcokxaQo/CZ9lUgUD7hhU+SXOWMTKaMg0qTfX/toAuRDTLzEaGEPHgJVF1u/abvx0ELHagp4=", + "postfix": " -17" + }, + { + "dmdv3Address": "dbaZF6CoeW5vX6YQPFQJuNPGZUepojGQfg", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IMIoXoaMBwa0kiotWBPglrWM+RFwyv2NcKBi/Y2UvPkSMK2rQ3Mb0xM1ruaxxgEO5I3wO6jzOhTPqOEmOhnXSm0=", + "postfix": " -18" + }, + { + "dmdv3Address": "dTwWDLrEf8VRSpgpENhb4DdfkNLuNandVD", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IHaomhAdpDQL+QEWL6mXsEHHMl9tlvjpgdnNEwtUPT8wcnnO+4PLH7AN8IG4pm9mPlNrEKHa2r8kBJsyMCthwiA=", + "postfix": " -19" + } + ] + } \ No newline at end of file diff --git a/test/testdata/with_postfixes.json b/test/testdata/with_postfixes.json new file mode 100644 index 0000000..2598b34 --- /dev/null +++ b/test/testdata/with_postfixes.json @@ -0,0 +1,75 @@ +{ + "messagePrefix": "claim to: ", + "balances": [ + { + "dmdv3Address": "dKoDxdQXemnyq4nEx9Qg1vo6xbFLkDLCeS", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IGrF5yu1HkMT5JkxBCAbDT78UGUoCgRDWtaYZgDSpsp6Dril0v1PNZcWRoYPeJd4QEUo7hdIiWHPsKgk2vFu4zM=", + "postfix": "" + }, + { + "dmdv3Address": "dE8eQXMGvdBFhUa42fnGwpru3iRPdDcPJL", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IFEWZeRNsxLwaQmKOXB9373Ct6lALrMIrRiRTX5+uTEoRPXwPmvEheqYYY/OqHxK5VvXsy49IkZrBvHl1Q18Ado=", + "postfix": " -1" + }, + { + "dmdv3Address": "dMfsCCttzYb9DhkQ4KoYBGfSuzKJ3G3jfA", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IEd83V2Jyhbm5+5CNsYaNUtiH3MNyySV47HwXkAabuU1cMkt/3md+f75ejOHoSNWg3oLtmcTLdSfWjfIjL18czI=", + "postfix": "" + }, + { + "dmdv3Address": "dRnz8sahtS83WXRAzDLYp8nbrpFTN4edvK", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IOJoTwHju57HhQmRGAtehyW+KGnFZCL7SYbktKr6GTjtNig89peg0xZNQv9dGVDt9A3bZ/i9SIClgrZ80yeiSOQ=", + "postfix": " -3" + }, + { + "dmdv3Address": "dZR8sL5wtJgwyMcfrAWsAhCoLyCWRJRdNd", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "ICIEHTeA8+bdXbTRLOwNRA2O5Kqc334SexLFIuzHZOPrFYgJ9ulUH5ID2qpLMCH3KrDwbeb6GHhuZMrkBSrVHOE=", + "postfix": " -4" + }, + { + "dmdv3Address": "dXYqxZunxfJsyMjzVrMVKQku6qHCPbDvNo", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IFix7TxV2wvKtPANF6NcQ1n2ZM04mwoNkGgn3Wm0zZvlEorjwChDGyS8cJWa1VyFMq2LkuXG8H5MsAYatenUBCo=", + "postfix": " -5" + }, + { + "dmdv3Address": "dYxJ61h5ZuCL2NYBniWzui7B2vYdBfD8mX", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IOo7zCVtObZLOCu+5wY3BqO04NRv5dFBijh0arf2M0mlOkMexcYRQZEHY4GrjR+fym3fZiDeCuIIcvkLsQV8wV4=", + "postfix": " -6" + }, + { + "dmdv3Address": "dHBrAZzuittub9f8F2c5C7DaXD1KtBPwxi", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "INcBYlSEbdNjjI1GHPYVfZTLFWlsFwVBgMg0/nZsOS66HKhBbS5TzJ3QP7hU9KHeHh5ISRjW7o9o4qNP8ZKuVyY=", + "postfix": "" + }, + { + "dmdv3Address": "dMzCVR54QZm1EQeX6sdnqF3WMy7Lrfkxox", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "IKkfrI1iT7/edRbJ1pgtjdY1annuZIkwsYDhNX+fYm3lE4emooIF4DPTvSvI49V4wa5V/pDQRGyInHvty7s6/lQ=", + "postfix": "" + }, + { + "dmdv3Address": "dcJciN8svxCQYuEerwWqbDBWvaFYC3MhoK", + "dmdv4Address": "0xbb753f1126c2463Ac29e175B180dAE7F7f627fA4", + "value": "10000", + "signature": "INs9iRwVQbHPe5S0JYiJt8pDjJ7BI5ZQfn5j9ufQGq49B+Sdw5vKVz6LTI/0H9LRgICejl6G2EZybK3kpKAEoQs=", + "postfix": " -9" + } + ] + } \ No newline at end of file