-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate_elections.py
138 lines (116 loc) · 4.07 KB
/
create_elections.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env python
"""
This module manages the elections on the blockchain. It creates a new
batch of voting tokens and distributes it to the given pubkeys.
"""
import argparse
import binascii
import csv
import hashlib
import json
import logging
import base58
from Savoir import Savoir
__author__ = "Daan Middendorp"
__copyright__ = "Copyright 2017, Digital Voting Pass"
__credits__ = ["Wilko Meijer", "Daan Middendorp", "Jonathan Raes", "Rico Tubbing"]
__license__ = "GPL"
__version__ = "0.0.1"
def main():
"""
Handles application workflow
"""
addresses = get_addresses()
issue_tokens(__args__.tokenname, len(addresses))
grant_permissions(addresses)
distribute_tokens(__args__.tokenname, addresses)
def distribute_tokens(name, addresses):
"""
Send every address one token
"""
success = 0
for address in addresses:
if isinstance(__api__.sendasset(address, name, 1), basestring):
success += 1
print str(success) + " token(s) distributed over " + str(len(addresses)) + " address(es)"
def grant_permissions(addresses):
"""
Grant send and receive permissions to addresses
"""
__api__.grant(", ".join(addresses), "send")
__api__.grant(", ".join(addresses), "receive")
def issue_tokens(name, amount):
"""
Create a transaction which issues n assets with the given name
"""
# Get wallet address of host
issue_permissions = __api__.listpermissions('issue')
host_wallet_address = issue_permissions[0]['address']
print "Host wallet address: " + host_wallet_address
# Issue assets with given amount
transaction = __api__.issue(host_wallet_address, name, amount, 1)
if not isinstance(transaction, basestring):
if transaction['error']['code'] == -705:
raise Exception('Token already issued, try a different name')
print str(amount) + " token(s) of " + name + " issued"
return transaction
def get_addresses():
"""
Converts the public keys in the csv to list of addresses
"""
addresses = []
with open(__args__.pubkeys, 'rb') as csvfile:
for row in csv.reader(csvfile, delimiter=' ', quotechar='|'):
addresses.append(pubkey_to_address(row[0], __config__))
return addresses
def pubkey_to_address(pubkey, config):
"""
Returns a valid address on the blockchain for pubkey
According to http://www.multichain.com/developers/address-key-format/
"""
# Step 3
pubkey_hash = hashlib.sha256(binascii.unhexlify(pubkey))
ripemd160 = hashlib.new('ripemd160')
ripemd160.update(pubkey_hash.digest())
# Step 4
pubkey160_hash = ripemd160.hexdigest()
# Step 5
pubkey160_hash_w_version = ''
for i in range(4):
pubkey160_hash_w_version += config['version'][i] + pubkey160_hash[(i*10):(i*10)+10]
# Step 6
sha256_of_160hash = hashlib.sha256(binascii.unhexlify(pubkey160_hash_w_version))
sha256_of_160hash.hexdigest()
# Step 7
sha256_of_prev_sha256 = hashlib.sha256(sha256_of_160hash.digest())
# Step 8
checksum = sha256_of_prev_sha256.hexdigest()[0:8]
# Step 9
xor_checksum = '{:08x}'.format(int(int(checksum, 16) ^ int(config['addresschecksum'], 16)))
# Step 10
binary_address = pubkey160_hash_w_version + xor_checksum
# Step 11
return base58.b58encode(binascii.unhexlify(binary_address))
def parse_args():
"""
Return parsed arguments as object
"""
parser = argparse.ArgumentParser(
description='Create new elections and assign one token to every pubkey'
)
parser.add_argument('--tokenname', '-n', required=True)
parser.add_argument('--pubkeys', '-i', required=True)
parser.add_argument('--config', '-c', required=False, default="config.json")
return parser.parse_args()
if __name__ == '__main__':
logging.basicConfig(level=logging.ERROR)
__args__ = parse_args()
__config__ = json.load(open(__args__.config))
__api__ = Savoir(
__config__['rpcuser'],
__config__['rpcpasswd'],
__config__['rpchost'],
__config__['rpcport'],
__config__['chainname']
)
main()