From 727bb4a38563bf1cd844203a5d391fa6f98c63c8 Mon Sep 17 00:00:00 2001 From: Eugene Nichegovskiy Date: Thu, 31 Jan 2019 17:35:56 +0300 Subject: [PATCH 01/13] verified voting --- .../VoteInitiatorSmartAccount.ride | 23 +++++++ .../verified-voting/VotingAssetScript.ride | 61 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 applications/verified-voting/VoteInitiatorSmartAccount.ride create mode 100644 applications/verified-voting/VotingAssetScript.ride diff --git a/applications/verified-voting/VoteInitiatorSmartAccount.ride b/applications/verified-voting/VoteInitiatorSmartAccount.ride new file mode 100644 index 0000000..5ce971b --- /dev/null +++ b/applications/verified-voting/VoteInitiatorSmartAccount.ride @@ -0,0 +1,23 @@ + +#deny account data modification if account already voted +#at the voting start only (address, boolean) data stored to account +#voter should send binary with address as key and signature+vote transaction id as value + +let this = extract(tx.sender) + +match (tx) { + case d:DataTransaction => + if (size(d.data) == 1 && isDefined(getBoolean(this, d.data[0].key))) then + if (!isDefined(getBinary(this,d.data[0].key))) then + size(extract(getBinary(d.data, 0))) > 64 + && addressFromPublicKey(d.proofs[0]) == addressFromString(d.data[0].key) + && sigVerify(d.bodyBytes, d.proofs[1], d.proofs[0]) + else + throw("account already voted") + else + false + case s:SetScriptTransaction => + false + case _ => + true +} \ No newline at end of file diff --git a/applications/verified-voting/VotingAssetScript.ride b/applications/verified-voting/VotingAssetScript.ride new file mode 100644 index 0000000..f6040c6 --- /dev/null +++ b/applications/verified-voting/VotingAssetScript.ride @@ -0,0 +1,61 @@ +let voteBankPublicKey = fromBase58String("") +let voteBank = addressFromPublicKey(voteBankPublicKey) + +match (tx) { + case t:TransferTransaction => + let issueTx = transactionById(extract(t.assetId)) + + match (issueTx){ + case issueTx:IssueTransaction => + #asset can be transfered to voteReg account if vote registred in data: key - assetID, value - max voting height + #from voteReg account to specific vote-variants addresses - checked by vote bank account script + #tokens quantity should be equal to number of voters + #all issued tokens should be transfered to voteReg account + let q = issueTx.description + let regAssetForVoting = getInteger(voteBank, toBase58String(issueTx.id)) + if (t.sender == issueTx.sender) then + let votingAssetConditionsMet = isDefined(regAssetForVoting) + && t.recipient == voteBank + && !issueTx.reissuable + && issueTx.quantity == t.amount + && issueTx.decimals == 0 + if (votingAssetConditionsMet) then + #voting account in issuer data should be protected from unfirified override + let accountScriptHash = extract(getBinary(voteBank, "IssuerAccountScriptHash")) + let accountScriptedProof = extract(getBinary(voteBank, toBase58String(issueTx.sender.bytes))) + let scriptTx = transactionById(accountScriptedProof) + match (scriptTx){ + case s:SetScriptTransaction => + sha256(extract(s.script)) == accountScriptHash + case _ => + false + } + else + throw("start voting conditions not met. Voting not registred or wrong asset") + else + #voter should be registred using data tx to issuer address + #voter registration id should be equal to transfer (voting) transaction id + #if reg number exists in blockchain, then voter already voted + + let voterPublicKey = take(t.attachment, 32) + let voterAddress = addressFromPublicKey(voterPublicKey) + let voterRegId = getBinary(issueTx.sender, toBase58String(voterAddress.bytes)) + if (isDefined(voterRegId)) then + let voterSignature = take(extract(voterRegId), 64) + let voterTxId = drop(extract(voterRegId), 64) + t.senderPublicKey == voteBankPublicKey + && t.id == voterTxId + && t.amount == 1 + && t.fee < 10000000 + && !isDefined(transactionById(voterTxId)) + && sigVerify(t.bodyBytes, voterSignature, voterPublicKey) + else + false + case _ => + false + } + case x:SetAssetScriptTransaction => + true + case _ => + false +} \ No newline at end of file From 3d3e93825be4771e6ca2b5c392b38eb4daf07de8 Mon Sep 17 00:00:00 2001 From: Eugene Nichegovskiy Date: Thu, 31 Jan 2019 19:31:35 +0300 Subject: [PATCH 02/13] verified voting --- .../verified-voting/VotingAssetScript.ride | 1 - .../verified-voting/VotingRegistrator.ride | 49 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 applications/verified-voting/VotingRegistrator.ride diff --git a/applications/verified-voting/VotingAssetScript.ride b/applications/verified-voting/VotingAssetScript.ride index f6040c6..dee6bba 100644 --- a/applications/verified-voting/VotingAssetScript.ride +++ b/applications/verified-voting/VotingAssetScript.ride @@ -18,7 +18,6 @@ match (tx) { && t.recipient == voteBank && !issueTx.reissuable && issueTx.quantity == t.amount - && issueTx.decimals == 0 if (votingAssetConditionsMet) then #voting account in issuer data should be protected from unfirified override let accountScriptHash = extract(getBinary(voteBank, "IssuerAccountScriptHash")) diff --git a/applications/verified-voting/VotingRegistrator.ride b/applications/verified-voting/VotingRegistrator.ride new file mode 100644 index 0000000..ce6e13b --- /dev/null +++ b/applications/verified-voting/VotingRegistrator.ride @@ -0,0 +1,49 @@ +let voteBank = addressFromPublicKey(fromBase58String("")) +let minimalVotingHeight = 100 + +match (tx) { + case d:DataTransaction => + if (size(d.data) == 1) then + #sender should place waves-transfer txId to pay fees for voting in proof[0] of data tx + let feeTransferId = transactionById(d.proofs[0]) + match (feeTransferId) { + case fT:TransferTransaction => + let votingHeight = extract(getInteger(d.data,1)) + !isDefined(getString(voteBank, d.data[0].key)) + && fT.recipient == voteBank + && votingHeight > height + && votingHeight - height > minimalVotingHeight + + #script should guaranty that user payed fees for all transfers + #asset should not have decimals to prevent satoshi calculation + && match(transactionById(fromBase58String(d.data[0].key))){ + case i:IssueTransaction => + if (fT.amount >= i.quantity * 900000) then + i.decimals == 0 + && fT.senderPublicKey == i.senderPublicKey + && sigVerify(d.bodyBytes, d.proofs[1], fT.senderPublicKey) + else + throw("minimum trasfer transaction amount is" + toString(i.quantity * 900000)) + case _ => + false + } + case _ => + false + } + else + throw("data tx should contain only one key-value pair: assetId-maxVotingHeight") + case t:TransferTransaction => + if (isDefined(getInteger(voteBank, toBase58String(extract(t.assetId))))) then + let h = getInteger(voteBank, toBase58String(extract(t.assetId))) + (extract(h) <= height) + && (addressFromRecipient(t.recipient) == addressFromString(extract(getString(voteBank, "pros"))) + || addressFromRecipient(t.recipient) == addressFromString(extract(getString(voteBank, "cons")))) + && isDefined(getString(voteBank, "pros")) + && isDefined(getString(voteBank, "cons")) + else + throw("you cannot vote with this token. It's not registred") + case s:SetScriptTransaction => + sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) + case _ => + false + } \ No newline at end of file From c44b6954b9e247ee411d3ee4212c71750f19ae2a Mon Sep 17 00:00:00 2001 From: Eugene Nichegovskiy Date: Thu, 31 Jan 2019 20:04:03 +0300 Subject: [PATCH 03/13] verified voting --- .../verified-voting/VotingAssetScript.ride | 15 +++------------ .../verified-voting/VotingRegistrator.ride | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/applications/verified-voting/VotingAssetScript.ride b/applications/verified-voting/VotingAssetScript.ride index dee6bba..92bb7bd 100644 --- a/applications/verified-voting/VotingAssetScript.ride +++ b/applications/verified-voting/VotingAssetScript.ride @@ -1,4 +1,4 @@ -let voteBankPublicKey = fromBase58String("") +let voteBankPublicKey = fromBase58String("azWhyNMQjEY9AQt2eySXXqR28NJwEbJTKy132zkVoTe") let voteBank = addressFromPublicKey(voteBankPublicKey) match (tx) { @@ -11,24 +11,15 @@ match (tx) { #from voteReg account to specific vote-variants addresses - checked by vote bank account script #tokens quantity should be equal to number of voters #all issued tokens should be transfered to voteReg account - let q = issueTx.description let regAssetForVoting = getInteger(voteBank, toBase58String(issueTx.id)) if (t.sender == issueTx.sender) then let votingAssetConditionsMet = isDefined(regAssetForVoting) && t.recipient == voteBank && !issueTx.reissuable && issueTx.quantity == t.amount + && issueTx.decimals == 0 if (votingAssetConditionsMet) then - #voting account in issuer data should be protected from unfirified override - let accountScriptHash = extract(getBinary(voteBank, "IssuerAccountScriptHash")) - let accountScriptedProof = extract(getBinary(voteBank, toBase58String(issueTx.sender.bytes))) - let scriptTx = transactionById(accountScriptedProof) - match (scriptTx){ - case s:SetScriptTransaction => - sha256(extract(s.script)) == accountScriptHash - case _ => - false - } + true else throw("start voting conditions not met. Voting not registred or wrong asset") else diff --git a/applications/verified-voting/VotingRegistrator.ride b/applications/verified-voting/VotingRegistrator.ride index ce6e13b..1fe4e74 100644 --- a/applications/verified-voting/VotingRegistrator.ride +++ b/applications/verified-voting/VotingRegistrator.ride @@ -3,9 +3,10 @@ let minimalVotingHeight = 100 match (tx) { case d:DataTransaction => - if (size(d.data) == 1) then + if (size(d.data) == 2) then #sender should place waves-transfer txId to pay fees for voting in proof[0] of data tx let feeTransferId = transactionById(d.proofs[0]) + match (feeTransferId) { case fT:TransferTransaction => let votingHeight = extract(getInteger(d.data,1)) @@ -18,8 +19,18 @@ match (tx) { #asset should not have decimals to prevent satoshi calculation && match(transactionById(fromBase58String(d.data[0].key))){ case i:IssueTransaction => + let accountScriptedProof = extract(getBinary(d.data, 1)) + let accountScriptHash = extract(getBinary(voteBank, "IssuerAccountScriptHash")) + let scriptTx = transactionById(accountScriptedProof) + if (fT.amount >= i.quantity * 900000) then - i.decimals == 0 + match (scriptTx){ + case s:SetScriptTransaction => + sha256(extract(s.script)) == accountScriptHash + case _ => + throw("voting initiator not scripted, or script is wrong") + } + && i.decimals == 0 && fT.senderPublicKey == i.senderPublicKey && sigVerify(d.bodyBytes, d.proofs[1], fT.senderPublicKey) else From 5a3eaf2ab2cdc28aecff106e57ba554e7239522e Mon Sep 17 00:00:00 2001 From: Eugene Nichegovskiy Date: Sat, 2 Feb 2019 01:48:05 +0300 Subject: [PATCH 04/13] verified voting --- .../VoteInitiatorSmartAccount.ride | 14 ++++++++------ .../verified-voting/VotingAssetScript.ride | 7 ++----- .../verified-voting/VotingRegistrator.ride | 17 ++++++++++------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/applications/verified-voting/VoteInitiatorSmartAccount.ride b/applications/verified-voting/VoteInitiatorSmartAccount.ride index 5ce971b..29c7e2d 100644 --- a/applications/verified-voting/VoteInitiatorSmartAccount.ride +++ b/applications/verified-voting/VoteInitiatorSmartAccount.ride @@ -7,15 +7,17 @@ let this = extract(tx.sender) match (tx) { case d:DataTransaction => - if (size(d.data) == 1 && isDefined(getBoolean(this, d.data[0].key))) then - if (!isDefined(getBinary(this,d.data[0].key))) then - size(extract(getBinary(d.data, 0))) > 64 + if (size(d.data) == 1 && isDefined(getBinary(this,d.data[0].key))) then + throw("account already voted") + else + if (isDefined(getBoolean(this, d.data[0].key))) then + let regConditionsMet = size(extract(getBinary(d.data, 0))) > 64 && addressFromPublicKey(d.proofs[0]) == addressFromString(d.data[0].key) && sigVerify(d.bodyBytes, d.proofs[1], d.proofs[0]) + regConditionsMet || throw("cannot reg account with invalid voting contitions") else - throw("account already voted") - else - false + throw("account not in voting list") + case s:SetScriptTransaction => false case _ => diff --git a/applications/verified-voting/VotingAssetScript.ride b/applications/verified-voting/VotingAssetScript.ride index 92bb7bd..1b8324e 100644 --- a/applications/verified-voting/VotingAssetScript.ride +++ b/applications/verified-voting/VotingAssetScript.ride @@ -1,4 +1,4 @@ -let voteBankPublicKey = fromBase58String("azWhyNMQjEY9AQt2eySXXqR28NJwEbJTKy132zkVoTe") +let voteBankPublicKey = fromBase58String("CXpiWubcdkB79QekRVaEXMVY8N12qP2f9zJp5sziGfge") let voteBank = addressFromPublicKey(voteBankPublicKey) match (tx) { @@ -18,10 +18,7 @@ match (tx) { && !issueTx.reissuable && issueTx.quantity == t.amount && issueTx.decimals == 0 - if (votingAssetConditionsMet) then - true - else - throw("start voting conditions not met. Voting not registred or wrong asset") + votingAssetConditionsMet || throw("start voting conditions not met. Voting not registred or wrong asset") else #voter should be registred using data tx to issuer address #voter registration id should be equal to transfer (voting) transaction id diff --git a/applications/verified-voting/VotingRegistrator.ride b/applications/verified-voting/VotingRegistrator.ride index 1fe4e74..821c1c7 100644 --- a/applications/verified-voting/VotingRegistrator.ride +++ b/applications/verified-voting/VotingRegistrator.ride @@ -1,19 +1,21 @@ -let voteBank = addressFromPublicKey(fromBase58String("")) +let voteBank = tx.sender let minimalVotingHeight = 100 match (tx) { case d:DataTransaction => if (size(d.data) == 2) then #sender should place waves-transfer txId to pay fees for voting in proof[0] of data tx + #sender signature in proof[1] let feeTransferId = transactionById(d.proofs[0]) match (feeTransferId) { case fT:TransferTransaction => - let votingHeight = extract(getInteger(d.data,1)) + let votingHeight = extract(getInteger(d.data,0)) !isDefined(getString(voteBank, d.data[0].key)) && fT.recipient == voteBank + && !isDefined(fT.assetId) && votingHeight > height - && votingHeight - height > minimalVotingHeight + && votingHeight - height >= minimalVotingHeight #script should guaranty that user payed fees for all transfers #asset should not have decimals to prevent satoshi calculation @@ -28,21 +30,22 @@ match (tx) { case s:SetScriptTransaction => sha256(extract(s.script)) == accountScriptHash case _ => - throw("voting initiator not scripted, or script is wrong") + throw("voting initiator not scripted, or script is wrong") } && i.decimals == 0 && fT.senderPublicKey == i.senderPublicKey + && d.data[1].key == toBase58String(i.sender.bytes) && sigVerify(d.bodyBytes, d.proofs[1], fT.senderPublicKey) else throw("minimum trasfer transaction amount is" + toString(i.quantity * 900000)) case _ => - false + throw("data key at 0 index should contain voting asset id") } case _ => - false + throw("proof at index 0 doesn't contain fee transfer transaction") } else - throw("data tx should contain only one key-value pair: assetId-maxVotingHeight") + throw("data tx should contain two key-value pairs: 0 - assetId-maxVotingHeight, 1 - ") case t:TransferTransaction => if (isDefined(getInteger(voteBank, toBase58String(extract(t.assetId))))) then let h = getInteger(voteBank, toBase58String(extract(t.assetId))) From b993a27b52c05f58fa90eec16cbf06095734e154 Mon Sep 17 00:00:00 2001 From: enichegovskiy Date: Sun, 3 Feb 2019 19:45:52 +0300 Subject: [PATCH 05/13] KYC voting. --- .../VoteInitiatorSmartAccount.ride | 8 ++--- .../verified-voting/VotingAssetScript.ride | 33 +++++++++---------- .../verified-voting/VotingRegistrator.ride | 17 ++++++---- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/applications/verified-voting/VoteInitiatorSmartAccount.ride b/applications/verified-voting/VoteInitiatorSmartAccount.ride index 29c7e2d..56ef089 100644 --- a/applications/verified-voting/VoteInitiatorSmartAccount.ride +++ b/applications/verified-voting/VoteInitiatorSmartAccount.ride @@ -11,13 +11,11 @@ match (tx) { throw("account already voted") else if (isDefined(getBoolean(this, d.data[0].key))) then - let regConditionsMet = size(extract(getBinary(d.data, 0))) > 64 - && addressFromPublicKey(d.proofs[0]) == addressFromString(d.data[0].key) - && sigVerify(d.bodyBytes, d.proofs[1], d.proofs[0]) - regConditionsMet || throw("cannot reg account with invalid voting contitions") + (size(extract(getBinary(d.data, 0))) > 64 || throw("data not includes signature value")) + && (addressFromPublicKey(d.proofs[0]) == addressFromString(d.data[0].key) || throw("proof at idx 0 should contain voter public key")) + && (sigVerify(d.bodyBytes, d.proofs[1], d.proofs[0]) || throw("invalid tx signature")) else throw("account not in voting list") - case s:SetScriptTransaction => false case _ => diff --git a/applications/verified-voting/VotingAssetScript.ride b/applications/verified-voting/VotingAssetScript.ride index 1b8324e..24f260f 100644 --- a/applications/verified-voting/VotingAssetScript.ride +++ b/applications/verified-voting/VotingAssetScript.ride @@ -4,7 +4,6 @@ let voteBank = addressFromPublicKey(voteBankPublicKey) match (tx) { case t:TransferTransaction => let issueTx = transactionById(extract(t.assetId)) - match (issueTx){ case issueTx:IssueTransaction => #asset can be transfered to voteReg account if vote registred in data: key - assetID, value - max voting height @@ -13,36 +12,36 @@ match (tx) { #all issued tokens should be transfered to voteReg account let regAssetForVoting = getInteger(voteBank, toBase58String(issueTx.id)) if (t.sender == issueTx.sender) then - let votingAssetConditionsMet = isDefined(regAssetForVoting) - && t.recipient == voteBank - && !issueTx.reissuable - && issueTx.quantity == t.amount - && issueTx.decimals == 0 - votingAssetConditionsMet || throw("start voting conditions not met. Voting not registred or wrong asset") + (t.recipient == voteBank || throw("token recipient is not vote registrator acc")) + &&(isDefined(regAssetForVoting) || throw("asset should be registed before transfer")) + && (!issueTx.reissuable || throw("token should not be reissuable")) + && (issueTx.quantity == t.amount || throw("all issued quantity should be transfered to registrator")) + && issueTx.decimals == 0 else #voter should be registred using data tx to issuer address #voter registration id should be equal to transfer (voting) transaction id #if reg number exists in blockchain, then voter already voted - - let voterPublicKey = take(t.attachment, 32) + let voterPublicKey = t.attachment let voterAddress = addressFromPublicKey(voterPublicKey) let voterRegId = getBinary(issueTx.sender, toBase58String(voterAddress.bytes)) if (isDefined(voterRegId)) then let voterSignature = take(extract(voterRegId), 64) let voterTxId = drop(extract(voterRegId), 64) - t.senderPublicKey == voteBankPublicKey - && t.id == voterTxId - && t.amount == 1 - && t.fee < 10000000 - && !isDefined(transactionById(voterTxId)) - && sigVerify(t.bodyBytes, voterSignature, voterPublicKey) + if (t.id == voterTxId) then + t.senderPublicKey == voteBankPublicKey + && (t.amount == 1 || throw("only one voice allowed")) + && t.fee == 900000 + && (!isDefined(transactionById(voterTxId)) || throw("voter already voted")) + && (sigVerify(t.bodyBytes, voterSignature, voterPublicKey) || throw("wrong signature")) + else + throw("wrong tx id registred") else - false + throw("voter not registred") case _ => false } case x:SetAssetScriptTransaction => - true + throw("token script cannot be modified") case _ => false } \ No newline at end of file diff --git a/applications/verified-voting/VotingRegistrator.ride b/applications/verified-voting/VotingRegistrator.ride index 821c1c7..5a2f112 100644 --- a/applications/verified-voting/VotingRegistrator.ride +++ b/applications/verified-voting/VotingRegistrator.ride @@ -11,11 +11,11 @@ match (tx) { match (feeTransferId) { case fT:TransferTransaction => let votingHeight = extract(getInteger(d.data,0)) - !isDefined(getString(voteBank, d.data[0].key)) - && fT.recipient == voteBank + (!isDefined(getInteger(voteBank, d.data[0].key)) || throw("asset already registred")) + && (fT.recipient == voteBank || throw("fee recipient not votebank")) && !isDefined(fT.assetId) && votingHeight > height - && votingHeight - height >= minimalVotingHeight + && (votingHeight - height >= minimalVotingHeight || throw("voting interval should be more than 100 blocks")) #script should guaranty that user payed fees for all transfers #asset should not have decimals to prevent satoshi calculation @@ -26,16 +26,19 @@ match (tx) { let scriptTx = transactionById(accountScriptedProof) if (fT.amount >= i.quantity * 900000) then + #voting initiator account should be scripted match (scriptTx){ case s:SetScriptTransaction => - sha256(extract(s.script)) == accountScriptHash + ((sha256(extract(s.script)) == accountScriptHash) + || throw("script hash not fit requirements")) case _ => throw("voting initiator not scripted, or script is wrong") } && i.decimals == 0 && fT.senderPublicKey == i.senderPublicKey - && d.data[1].key == toBase58String(i.sender.bytes) - && sigVerify(d.bodyBytes, d.proofs[1], fT.senderPublicKey) + && (d.data[1].key == toBase58String(i.sender.bytes) || throw("trying to reg asset of another issuer")) + && (fromBase58String(d.data[0].key) == fT.attachment || throw("fee should be paid for voting asset, put assetId to attachment") + && (sigVerify(d.bodyBytes, d.proofs[1], fT.senderPublicKey) || throw("wrong signature")) else throw("minimum trasfer transaction amount is" + toString(i.quantity * 900000)) case _ => @@ -49,7 +52,7 @@ match (tx) { case t:TransferTransaction => if (isDefined(getInteger(voteBank, toBase58String(extract(t.assetId))))) then let h = getInteger(voteBank, toBase58String(extract(t.assetId))) - (extract(h) <= height) + (extract(h) > height) && (addressFromRecipient(t.recipient) == addressFromString(extract(getString(voteBank, "pros"))) || addressFromRecipient(t.recipient) == addressFromString(extract(getString(voteBank, "cons")))) && isDefined(getString(voteBank, "pros")) From f2d31d1dedb7dd98f2861aaf14154f7a7ca4761a Mon Sep 17 00:00:00 2001 From: enichegovskiy Date: Mon, 4 Feb 2019 00:55:51 +0300 Subject: [PATCH 06/13] KYC voting. --- applications/verified-voting/ReadMe.md | 79 +++++++++++++++++++ .../verified-voting/VotingRegistrator.ride | 7 +- 2 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 applications/verified-voting/ReadMe.md diff --git a/applications/verified-voting/ReadMe.md b/applications/verified-voting/ReadMe.md new file mode 100644 index 0000000..851f6ca --- /dev/null +++ b/applications/verified-voting/ReadMe.md @@ -0,0 +1,79 @@ +# Sponsored KYC voting + + +Any user can init a voting with answers "pros" or "cons" with verified users. + +Any voting process should be registered at Voting Registrar Account + +Voting initiator account, voting assets (VA) and Voting Registrar Account (VR) should be scripted +Scripts can guarantee: +1. Voter selected only one choice "pros" or "cons" (send a token to one of these addresses) +2. Vote initiator payed fee for voting procedure +3. VRA account checks max voting height + + +##Script and voting details + +Voting Registrar Account should contain script that checks new voting registration process and users' voting +Before setting script to VR account data with addresses for voting answers should be created + +Data format: + +| Type | Key | Value | +| --------- |:--------:| ---------:| +| String | pros | Address | +| String | cons | Address | + +###After applying VotingRegistrar script users can initiate votes. + +###Voting Initiator (VI) account sets a data with verified accounts + +Data format: +| Type | Key | Value | +| --------- |:---------:| ---------:| +| Boolean | Address | true | + +###To register a new voting VI account should +1. Script own account using VotingInitiatorSmartAccount script +⋅⋅* Store tx id (setScriptTxId) +⋅⋅* Script is standard for all VI accounts. +⋅⋅* Script should not be modified as it's hash would be checked at voting registration process +2. Issue new asset with properties +⋅⋅* reissuable = false +⋅⋅* token decimals = 0 +⋅⋅* quantity is equal to number of voters +⋅⋅* description = voting question +3. Send Waves to pay fees for all voters. Save transaction Id (feeTransferId) +Transaction properties: +⋅⋅* amount = token quantity * 900_000 (where 900_000 is fee for one transfer tx - smartaccount fee + smartasset fee) +⋅⋅* attachment = assetId +4. Sign and send DataTransaction from VR account. +Transaction properties: +⋅⋅* proof at index 0 = feeTransferId +⋅⋅* proof at index 1 = signature. Tx should be signed by Voting Initiator account +Data format: +| Type | Key | Value | +| --------- |:----------:| -----------------:| +| Integer | assetID | max voting height | +| Binary | VI Address | setScriptTxId | + +If data appllied to VR account then you can start voting process + +###Voting process +User should register as a voter at Voting Initiator account and send his vote from VR account +1. To register as a voter user signs (not send) a transfer transaction and saves tx id and signature +Transaction properties: +⋅⋅* amount = 1 +⋅⋅* fee = 900_000 +⋅⋅* attachment = voter public key +2. Sends a data transaction from VR account: +Transaction properties: +⋅⋅* proof at index 0 = Voter public key +⋅⋅* proof at index 1 = signature. Tx should be signed by Voter account +Data format: +| Type | Key | Value | +| --------- |:-------------:| ----------------------------:| +| Binary | Voter Address | Signature + TransferTxId | + Signature + TransferTxId = signature bytes should be placed first and TransferTxId bytes are concated to signature + +3. Sends signed a transfer transaction to one of the voting results address. \ No newline at end of file diff --git a/applications/verified-voting/VotingRegistrator.ride b/applications/verified-voting/VotingRegistrator.ride index 5a2f112..b0b7141 100644 --- a/applications/verified-voting/VotingRegistrator.ride +++ b/applications/verified-voting/VotingRegistrator.ride @@ -11,7 +11,8 @@ match (tx) { match (feeTransferId) { case fT:TransferTransaction => let votingHeight = extract(getInteger(d.data,0)) - (!isDefined(getInteger(voteBank, d.data[0].key)) || throw("asset already registred")) + (!isDefined(getInteger(voteBank, d.data[0].key)) || throw("asset already registered")) + &&(!isDefined(getBinary(voteBank, d.data[1].key)) || throw("voting already registered")) && (fT.recipient == voteBank || throw("fee recipient not votebank")) && !isDefined(fT.assetId) && votingHeight > height @@ -37,7 +38,7 @@ match (tx) { && i.decimals == 0 && fT.senderPublicKey == i.senderPublicKey && (d.data[1].key == toBase58String(i.sender.bytes) || throw("trying to reg asset of another issuer")) - && (fromBase58String(d.data[0].key) == fT.attachment || throw("fee should be paid for voting asset, put assetId to attachment") + && (fromBase58String(d.data[0].key) == fT.attachment || throw("fee should be paid for voting asset, put assetId to attachment")) && (sigVerify(d.bodyBytes, d.proofs[1], fT.senderPublicKey) || throw("wrong signature")) else throw("minimum trasfer transaction amount is" + toString(i.quantity * 900000)) @@ -48,7 +49,7 @@ match (tx) { throw("proof at index 0 doesn't contain fee transfer transaction") } else - throw("data tx should contain two key-value pairs: 0 - assetId-maxVotingHeight, 1 - ") + throw("data tx should contain two key-value pairs: 0 - assetId-maxVotingHeight, 1 - voting initiator setScriptTx id") case t:TransferTransaction => if (isDefined(getInteger(voteBank, toBase58String(extract(t.assetId))))) then let h = getInteger(voteBank, toBase58String(extract(t.assetId))) From 5a7507e6a22875375d70eb9c036da345d4c9a310 Mon Sep 17 00:00:00 2001 From: enichegovskiy Date: Mon, 4 Feb 2019 00:58:16 +0300 Subject: [PATCH 07/13] KYC voting. --- applications/verified-voting/ReadMe.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/applications/verified-voting/ReadMe.md b/applications/verified-voting/ReadMe.md index 851f6ca..196cfd6 100644 --- a/applications/verified-voting/ReadMe.md +++ b/applications/verified-voting/ReadMe.md @@ -2,17 +2,17 @@ Any user can init a voting with answers "pros" or "cons" with verified users. - Any voting process should be registered at Voting Registrar Account -Voting initiator account, voting assets (VA) and Voting Registrar Account (VR) should be scripted +### Voting initiator account, voting assets (VA) and Voting Registrar Account (VR) should be scripted Scripts can guarantee: 1. Voter selected only one choice "pros" or "cons" (send a token to one of these addresses) 2. Vote initiator payed fee for voting procedure -3. VRA account checks max voting height +3. Voting finished at max voting height +4. Minimal voting interval is 100 blocks -##Script and voting details +## Script and voting details Voting Registrar Account should contain script that checks new voting registration process and users' voting Before setting script to VR account data with addresses for voting answers should be created @@ -24,16 +24,16 @@ Data format: | String | pros | Address | | String | cons | Address | -###After applying VotingRegistrar script users can initiate votes. +### After applying VotingRegistrar script users can initiate votes. -###Voting Initiator (VI) account sets a data with verified accounts +### Voting Initiator (VI) account sets a data with verified accounts Data format: | Type | Key | Value | | --------- |:---------:| ---------:| | Boolean | Address | true | -###To register a new voting VI account should +### To register a new voting VI account should 1. Script own account using VotingInitiatorSmartAccount script ⋅⋅* Store tx id (setScriptTxId) ⋅⋅* Script is standard for all VI accounts. From 3f1d303701912c96193ff6cc6023509df8475d70 Mon Sep 17 00:00:00 2001 From: enichegovskiy Date: Mon, 4 Feb 2019 01:00:26 +0300 Subject: [PATCH 08/13] KYC voting. --- applications/verified-voting/ReadMe.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/applications/verified-voting/ReadMe.md b/applications/verified-voting/ReadMe.md index 196cfd6..a591b9c 100644 --- a/applications/verified-voting/ReadMe.md +++ b/applications/verified-voting/ReadMe.md @@ -4,7 +4,7 @@ Any user can init a voting with answers "pros" or "cons" with verified users. Any voting process should be registered at Voting Registrar Account -### Voting initiator account, voting assets (VA) and Voting Registrar Account (VR) should be scripted +#### Voting initiator account, voting assets (VA) and Voting Registrar Account (VR) should be scripted Scripts can guarantee: 1. Voter selected only one choice "pros" or "cons" (send a token to one of these addresses) 2. Vote initiator payed fee for voting procedure @@ -24,16 +24,16 @@ Data format: | String | pros | Address | | String | cons | Address | -### After applying VotingRegistrar script users can initiate votes. +#### After applying VotingRegistrar script users can initiate votes. -### Voting Initiator (VI) account sets a data with verified accounts +#### Voting Initiator (VI) account sets a data with verified accounts Data format: | Type | Key | Value | -| --------- |:---------:| ---------:| +| --------- |:---------:|:---------:| | Boolean | Address | true | -### To register a new voting VI account should +#### To register a new voting VI account should 1. Script own account using VotingInitiatorSmartAccount script ⋅⋅* Store tx id (setScriptTxId) ⋅⋅* Script is standard for all VI accounts. @@ -53,13 +53,13 @@ Transaction properties: ⋅⋅* proof at index 1 = signature. Tx should be signed by Voting Initiator account Data format: | Type | Key | Value | -| --------- |:----------:| -----------------:| +| --------- |:----------:|:-----------------:| | Integer | assetID | max voting height | | Binary | VI Address | setScriptTxId | If data appllied to VR account then you can start voting process -###Voting process +### Voting process User should register as a voter at Voting Initiator account and send his vote from VR account 1. To register as a voter user signs (not send) a transfer transaction and saves tx id and signature Transaction properties: @@ -72,7 +72,7 @@ Transaction properties: ⋅⋅* proof at index 1 = signature. Tx should be signed by Voter account Data format: | Type | Key | Value | -| --------- |:-------------:| ----------------------------:| +| --------- |:-------------:|:----------------------------:| | Binary | Voter Address | Signature + TransferTxId | Signature + TransferTxId = signature bytes should be placed first and TransferTxId bytes are concated to signature From 737b2803373c0557c5ebcb3c6e994f9ffe73eafd Mon Sep 17 00:00:00 2001 From: enichegovskiy Date: Mon, 4 Feb 2019 01:02:58 +0300 Subject: [PATCH 09/13] KYC voting. --- applications/verified-voting/ReadMe.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/applications/verified-voting/ReadMe.md b/applications/verified-voting/ReadMe.md index a591b9c..efb3446 100644 --- a/applications/verified-voting/ReadMe.md +++ b/applications/verified-voting/ReadMe.md @@ -29,8 +29,9 @@ Data format: #### Voting Initiator (VI) account sets a data with verified accounts Data format: + | Type | Key | Value | -| --------- |:---------:|:---------:| +| --------- |:---------:| ---------:| | Boolean | Address | true | #### To register a new voting VI account should @@ -52,8 +53,9 @@ Transaction properties: ⋅⋅* proof at index 0 = feeTransferId ⋅⋅* proof at index 1 = signature. Tx should be signed by Voting Initiator account Data format: + | Type | Key | Value | -| --------- |:----------:|:-----------------:| +| --------- |:----------:| -----------------:| | Integer | assetID | max voting height | | Binary | VI Address | setScriptTxId | @@ -71,9 +73,11 @@ Transaction properties: ⋅⋅* proof at index 0 = Voter public key ⋅⋅* proof at index 1 = signature. Tx should be signed by Voter account Data format: + | Type | Key | Value | -| --------- |:-------------:|:----------------------------:| +| --------- |:-------------:| ----------------------------:| | Binary | Voter Address | Signature + TransferTxId | + Signature + TransferTxId = signature bytes should be placed first and TransferTxId bytes are concated to signature 3. Sends signed a transfer transaction to one of the voting results address. \ No newline at end of file From f5d796052f87e70e97eeed5eee1c8291a862812a Mon Sep 17 00:00:00 2001 From: enichegovskiy Date: Mon, 4 Feb 2019 01:04:11 +0300 Subject: [PATCH 10/13] KYC voting. --- applications/verified-voting/ReadMe.md | 32 +++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/applications/verified-voting/ReadMe.md b/applications/verified-voting/ReadMe.md index efb3446..d908095 100644 --- a/applications/verified-voting/ReadMe.md +++ b/applications/verified-voting/ReadMe.md @@ -36,22 +36,22 @@ Data format: #### To register a new voting VI account should 1. Script own account using VotingInitiatorSmartAccount script -⋅⋅* Store tx id (setScriptTxId) -⋅⋅* Script is standard for all VI accounts. -⋅⋅* Script should not be modified as it's hash would be checked at voting registration process + * Store tx id (setScriptTxId) + * Script is standard for all VI accounts. + * Script should not be modified as it's hash would be checked at voting registration process 2. Issue new asset with properties -⋅⋅* reissuable = false -⋅⋅* token decimals = 0 -⋅⋅* quantity is equal to number of voters -⋅⋅* description = voting question + * reissuable = false + * token decimals = 0 + * quantity is equal to number of voters + * description = voting question 3. Send Waves to pay fees for all voters. Save transaction Id (feeTransferId) Transaction properties: -⋅⋅* amount = token quantity * 900_000 (where 900_000 is fee for one transfer tx - smartaccount fee + smartasset fee) -⋅⋅* attachment = assetId + * amount = token quantity * 900_000 (where 900_000 is fee for one transfer tx - smartaccount fee + smartasset fee) + * attachment = assetId 4. Sign and send DataTransaction from VR account. Transaction properties: -⋅⋅* proof at index 0 = feeTransferId -⋅⋅* proof at index 1 = signature. Tx should be signed by Voting Initiator account + * proof at index 0 = feeTransferId + * proof at index 1 = signature. Tx should be signed by Voting Initiator account Data format: | Type | Key | Value | @@ -65,13 +65,13 @@ If data appllied to VR account then you can start voting process User should register as a voter at Voting Initiator account and send his vote from VR account 1. To register as a voter user signs (not send) a transfer transaction and saves tx id and signature Transaction properties: -⋅⋅* amount = 1 -⋅⋅* fee = 900_000 -⋅⋅* attachment = voter public key + * amount = 1 + * fee = 900_000 + * attachment = voter public key 2. Sends a data transaction from VR account: Transaction properties: -⋅⋅* proof at index 0 = Voter public key -⋅⋅* proof at index 1 = signature. Tx should be signed by Voter account + * proof at index 0 = Voter public key + * proof at index 1 = signature. Tx should be signed by Voter account Data format: | Type | Key | Value | From cdbfd940eefaf9199d8ee20d4eec6d1d8afbf6db Mon Sep 17 00:00:00 2001 From: enichegovskiy Date: Mon, 4 Feb 2019 01:06:45 +0300 Subject: [PATCH 11/13] KYC voting. --- applications/verified-voting/ReadMe.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/applications/verified-voting/ReadMe.md b/applications/verified-voting/ReadMe.md index d908095..3ad6825 100644 --- a/applications/verified-voting/ReadMe.md +++ b/applications/verified-voting/ReadMe.md @@ -7,9 +7,10 @@ Any voting process should be registered at Voting Registrar Account #### Voting initiator account, voting assets (VA) and Voting Registrar Account (VR) should be scripted Scripts can guarantee: 1. Voter selected only one choice "pros" or "cons" (send a token to one of these addresses) -2. Vote initiator payed fee for voting procedure -3. Voting finished at max voting height -4. Minimal voting interval is 100 blocks +2. Voter can take part in voting only once +3. Vote initiator payed fee for voting procedure +5. Voting finished at max voting height +6. Minimal voting interval is 100 blocks ## Script and voting details From 87df3b6bf6545b89aa088acb1ba549e71331681f Mon Sep 17 00:00:00 2001 From: enichegovskiy Date: Mon, 4 Feb 2019 01:11:27 +0300 Subject: [PATCH 12/13] KYC voting. --- applications/verified-voting/ReadMe.md | 1 + 1 file changed, 1 insertion(+) diff --git a/applications/verified-voting/ReadMe.md b/applications/verified-voting/ReadMe.md index 3ad6825..bb2e69e 100644 --- a/applications/verified-voting/ReadMe.md +++ b/applications/verified-voting/ReadMe.md @@ -24,6 +24,7 @@ Data format: | --------- |:--------:| ---------:| | String | pros | Address | | String | cons | Address | +| Binary| IssuerAccountScriptHash | H6pkCiqWzuHwQ1ktmusj9bNy5wsh3kvwdZx1Ch4NfoLi | #### After applying VotingRegistrar script users can initiate votes. From d34e0bd504a0880e68da9164e1db773387604b88 Mon Sep 17 00:00:00 2001 From: enichegovskiy Date: Mon, 4 Feb 2019 02:15:54 +0300 Subject: [PATCH 13/13] KYC voting. --- applications/verified-voting/ReadMe.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/applications/verified-voting/ReadMe.md b/applications/verified-voting/ReadMe.md index bb2e69e..335f0b5 100644 --- a/applications/verified-voting/ReadMe.md +++ b/applications/verified-voting/ReadMe.md @@ -61,7 +61,9 @@ Data format: | Integer | assetID | max voting height | | Binary | VI Address | setScriptTxId | -If data appllied to VR account then you can start voting process +5. If data appllied to VR account, send all issued token (amount = quantity) to VR account + +Now you can start voting. ### Voting process User should register as a voter at Voting Initiator account and send his vote from VR account