Goodmorning everyone,
I’m wrote a smart contract on TestNet to get a voting application.
The code has a compile error every time the client.compile(source_code) method is executed
I get an error like: AlgodHTTPError.
No more information on the type of error and why :
AlgodHTTPError (note: full exception trace is shown but execution is paused at: <module>)
1 error
During handling of the above exception, another exception occurred:
File "/mnt/c/Users/simon/algo-vsc/contratti/vote.py", line 119, in compile_program
compile_response = client.compile(source_code)
File "/mnt/c/Users/simon/algo-vsc/contratti/vote.py", line 430, in main
approval_program_compiled = compile_program(algod_client, approval_program_teal)
File "/mnt/c/Users/simon/algo-vsc/contratti/vote.py", line 512, in <module> (Current frame)
main()
below I attach the code used:
import base64
import datetime
from pyteal import *
from algosdk.future import transaction
from algosdk import account, mnemonic
from algosdk.v2client import algod
from pyteal import compileTeal, Mode
creator_mnemonic = ""
user_mnemonic = ""
# user declared algod connection parameters
algod_address = "https://testnet-algorand.api.purestake.io/ps2"
indexer_address = "https://testnet-algorand.api.purestake.io/idx2"
algod_token = ""
headers = {
"X-API-Key": algod_token,
}
def approval_program():
on_creation = Seq(
[
App.globalPut(Bytes("Creator"), Txn.sender()),
Assert(Txn.application_args.length() == Int(4)),
App.globalPut(Bytes("RegBegin"), Btoi(Txn.application_args[0])),
App.globalPut(Bytes("RegEnd"), Btoi(Txn.application_args[1])),
App.globalPut(Bytes("VoteBegin"), Btoi(Txn.application_args[2])),
App.globalPut(Bytes("VoteEnd"), Btoi(Txn.application_args[3])),
Return(Int(1)),
]
)
is_creator = Txn.sender() == App.globalGet(Bytes("Creator"))
get_vote_of_sender = App.localGetEx(Int(0), App.id(), Bytes("voted"))
on_closeout = Seq(
[
get_vote_of_sender,
If(
And(
Global.round() <= App.globalGet(Bytes("VoteEnd")),
get_vote_of_sender.hasValue(),
),
App.globalPut(
get_vote_of_sender.value(),
App.globalGet(get_vote_of_sender.value()) - Int(1),
),
),
Return(Int(1)),
]
)
on_register = Return(
And(
Global.round() >= App.globalGet(Bytes("RegBegin")),
Global.round() <= App.globalGet(Bytes("RegEnd")),
)
)
choice = Txn.application_args[1]
choice_tally = App.globalGet(choice)
on_vote = Seq(
[
Assert(
And(
Global.round() >= App.globalGet(Bytes("VoteBegin")),
Global.round() <= App.globalGet(Bytes("VoteEnd")),
)
),
get_vote_of_sender,
If(get_vote_of_sender.hasValue(), Return(Int(0))),
App.globalPut(choice, choice_tally + Int(1)),
App.localPut(Int(0), Bytes("voted"), choice),
Return(Int(1)),
]
)
program = Cond(
[Txn.application_id() == Int(0), on_creation],
[Txn.on_completion() == OnComplete.DeleteApplication, Return(is_creator)],
[Txn.on_completion() == OnComplete.UpdateApplication, Return(is_creator)],
[Txn.on_completion() == OnComplete.CloseOut, on_closeout],
[Txn.on_completion() == OnComplete.OptIn, on_register],
[Txn.application_args[0] == Bytes("vote"), on_vote],
)
return program
def clear_state_program():
get_vote_of_sender = App.localGetEx(Int(0), App.id(), Bytes("voted"))
program = Seq(
[
get_vote_of_sender,
If(
And(
Global.round() <= App.globalGet(Bytes("VoteEnd")),
get_vote_of_sender.hasValue(),
),
App.globalPut(
get_vote_of_sender.value(),
App.globalGet(get_vote_of_sender.value()) - Int(1),
),
),
Return(Int(1)),
]
)
return program
# helper function to compile program source
def compile_program(client, source_code):
compile_response = client.compile(source_code)
return base64.b64decode(compile_response['result'])
# helper function that converts a mnemonic passphrase into a private signing key
def get_private_key_from_mnemonic(mn):
private_key = mnemonic.to_private_key(mn)
return private_key
# helper function that waits for a given txid to be confirmed by the network
def wait_for_confirmation(client, txid):
last_round = client.status().get('last-round')
txinfo = client.pending_transaction_info(txid)
while not (txinfo.get('confirmed-round') and txinfo.get('confirmed-round') > 0):
print("Waiting for confirmation...")
last_round += 1
client.status_after_block(last_round)
txinfo = client.pending_transaction_info(txid)
print("Transaction {} confirmed in round {}.".format(txid, txinfo.get('confirmed-round')))
return txinfo
def wait_for_round(client, round):
last_round = client.status().get("last-round")
print(f"Waiting for round {round}")
while last_round < round:
last_round += 1
client.status_after_block(last_round)
print(f"Round {last_round}")
# create new application
def create_app(client,
private_key,
approval_program,
clear_program,
global_schema,
local_schema,
app_args):
# define sender as creator
sender = account.address_from_private_key(private_key)
# declare on_complete as NoOp
on_complete = transaction.OnComplete.NoOpOC.real
# get node suggested parameters
params = client.suggested_params()
# comment out the next two (2) lines to use suggested fees
params.flat_fee = True
params.fee = 1000
# create unsigned transaction
txn = transaction.ApplicationCreateTxn(sender, params, on_complete, \
approval_program, clear_program, \
global_schema, local_schema,
app_args)
# sign transaction
signed_txn = txn.sign(private_key)
tx_id = signed_txn.transaction.get_txid()
# send transaction
client.send_transactions([signed_txn])
# await confirmation
wait_for_confirmation(client, tx_id)
# display results
transaction_response = client.pending_transaction_info(tx_id)
app_id = transaction_response['application-index']
print("Created new app-id: ", app_id)
return app_id
# opt-in to application
def opt_in_app(client, private_key, index):
# declare sender
sender = account.address_from_private_key(private_key)
print("OptIn from account: ", sender)
# get node suggested parameters
params = client.suggested_params()
# comment out the next two (2) lines to use suggested fees
params.flat_fee = True
params.fee = 1000
# create unsigned transaction
txn = transaction.ApplicationOptInTxn(sender, params, index)
# sign transaction
signed_txn = txn.sign(private_key)
tx_id = signed_txn.transaction.get_txid()
# send transaction
client.send_transactions([signed_txn])
# await confirmation
wait_for_confirmation(client, tx_id)
# display results
transaction_response = client.pending_transaction_info(tx_id)
print("OptIn to app-id: ", transaction_response['txn']['txn']['apid'])
# call application
def call_app(client, private_key, index, app_args): # index = app_id
# declare sender
sender = account.address_from_private_key(private_key)
print("Call from account: ", sender)
# get node suggested parameters
params = client.suggested_params()
# comment out the next two (2) lines to use suggested fees
params.flat_fee = True
params.fee = 1000
# create unsigned transaction
txn = transaction.ApplicationNoOpTxn(sender, params, index, app_args)
# sign transaction
signed_txn = txn.sign(private_key)
tx_id = signed_txn.transaction.get_txid()
# send transaction
client.send_transactions([signed_txn])
# await confirmation
wait_for_confirmation(client, tx_id)
def format_state(state):
formatted = {}
for item in state:
key = item["key"]
value = item["value"]
formatted_key = base64.b64decode(key).decode("utf-8")
if value["type"] == 1:
# byte string
if formatted_key == "voted":
formatted_value = base64.b64decode(value["bytes"]).decode("utf-8")
else:
formatted_value = value["bytes"]
formatted[formatted_key] = formatted_value
else:
# integer
formatted[formatted_key] = value["uint"]
return formatted
# read user local state
def read_local_state(client, addr, app_id):
results = client.account_info(addr)
for local_state in results['apps-local-state']:
if local_state['id'] == app_id:
if "key-value" not in local_state:
return {}
return format_state(local_state["key-value"])
print(f"local_state of account {addr} for app_id {app_id}: ", local_state['key-value'])
return {}
# read app global state
def read_global_state(client, addr, app_id):
results = client.account_info(addr)
apps_created = results['created-apps']
for app in apps_created:
if app['id'] == app_id:
print(f"global_state for app_id {app_id}: ", app['params']['global-state'])
return format_state(app['params']['global-state'])
return{}
# update existing application
def update_app(client, private_key, app_id, approval_program, clear_program):
# declare sender
sender = account.address_from_private_key(private_key)
# # define initial value for key "timestamp"
# app_args = [b'initial value']
# get node suggested parameters
params = client.suggested_params()
# comment out the next two (2) lines to use suggested fees
params.flat_fee = True
params.fee = 1000
# create unsigned transaction
txn = transaction.ApplicationUpdateTxn(sender, params, app_id, \
approval_program, clear_program) # , app_args)
# sign transaction
signed_txn = txn.sign(private_key)
tx_id = signed_txn.transaction.get_txid()
# send transaction
client.send_transactions([signed_txn])
# await confirmation
wait_for_confirmation(client, tx_id)
# display results
transaction_response = client.pending_transaction_info(tx_id)
app_id = transaction_response['txn']['txn']['apid']
print("Updated existing app-id: ", app_id)
# delete application
def delete_app(client, private_key, index):
# declare sender
sender = account.address_from_private_key(private_key)
# get node suggested parameters
params = client.suggested_params()
# comment out the next two (2) lines to use suggested fees
params.flat_fee = True
params.fee = 1000
# create unsigned transaction
txn = transaction.ApplicationDeleteTxn(sender, params, index)
# sign transaction
signed_txn = txn.sign(private_key)
tx_id = signed_txn.transaction.get_txid()
# send transaction
client.send_transactions([signed_txn])
# await confirmation
wait_for_confirmation(client, tx_id)
# display results
transaction_response = client.pending_transaction_info(tx_id)
print("Deleted app-id: ", transaction_response['txn']['txn']['apid'])
# close out from application
def close_out_app(client, private_key, index):
# declare sender
sender = account.address_from_private_key(private_key)
# get node suggested parameters
params = client.suggested_params()
# comment out the next two (2) lines to use suggested fees
params.flat_fee = True
params.fee = 1000
# create unsigned transaction
txn = transaction.ApplicationCloseOutTxn(sender, params, index)
# sign transaction
signed_txn = txn.sign(private_key)
tx_id = signed_txn.transaction.get_txid()
# send transaction
client.send_transactions([signed_txn])
# await confirmation
wait_for_confirmation(client, tx_id)
# display results
transaction_response = client.pending_transaction_info(tx_id)
print("Closed out from app-id: ", transaction_response['txn']['txn']['apid'])
# clear application
def clear_app(client, private_key, index):
# declare sender
sender = account.address_from_private_key(private_key)
# get node suggested parameters
params = client.suggested_params()
# comment out the next two (2) lines to use suggested fees
params.flat_fee = True
params.fee = 1000
# create unsigned transaction
txn = transaction.ApplicationClearStateTxn(sender, params, index)
# sign transaction
signed_txn = txn.sign(private_key)
tx_id = signed_txn.transaction.get_txid()
# send transaction
client.send_transactions([signed_txn])
# await confirmation
wait_for_confirmation(client, tx_id)
# display results
transaction_response = client.pending_transaction_info(tx_id)
print("Cleared app-id: ", transaction_response['txn']['txn']['apid'])
def intToBytes(i):
return i.to_bytes(8, "big")
def main():
algod_client = algod.AlgodClient(algod_token, algod_address, headers=headers)
creator_private_key = get_private_key_from_mnemonic(creator_mnemonic)
user_private_key = get_private_key_from_mnemonic(user_mnemonic)
local_ints = 0
local_bytes = 1
global_ints = 24
global_bytes = 1
global_schema = transaction.StateSchema(global_ints, global_bytes)
local_schema = transaction.StateSchema(local_ints, local_bytes)
approval_program_ast = approval_program()
approval_program_teal = compileTeal(approval_program_ast, mode= Mode.Application)
approval_program_compiled = compile_program(algod_client, approval_program_teal)
clear_state_program_ast = clear_state_program()
clear_state_program_teal = compileTeal(clear_state_program_ast, mode = Mode.Application)
clear_state_program_compiled = compile_program(algod_client, clear_state_program_teal)
status = algod_client.status()
regBegin = status["last-round"] + 10
regEnd = regBegin + 10
voteBegin = regEnd + 1
voteEnd = voteBegin + 10
print(f"Registration rounds : {regBegin} to {regEnd}")
print(f"vote rounds: {voteBegin} to {voteEnd}")
app_args = [
intToBytes(regBegin),
intToBytes(regEnd),
intToBytes(voteBegin),
intToBytes(voteEnd),
]
app_id = create_app(algod_client, creator_private_key, approval_program_compiled, clear_program_compiled, global_schema, local_schema, app_args)
print("global state: ",
read_global_state(algod_client, account.address_from_private_key(creator_private_key), app_id),)
wait_for_round(algod_client, regBegin)
opt_in_app(algod_client, user_private_key, app_id)
print(
"local state:",
read_local_state(algod_client, account.address_from_private_key(user_private_key), app_id),
)
wait_for_round(algod_client, voteEnd)
global_state = read_global_state(algod_client, account.address_from_private_key(creator_private_key), app_id)
print("Global state: ", global_state)
max_votes = 0
max_votes_choice = None
for key, value in global_state.items():
if (
key
not in (
"RegBegin",
"RegEnd",
"VoteBegin",
"VoteEnd",
"Creator",
)
and isinstance(value, int)
):
if value > max_votes:
max_votes = value
max_votes_choice = key
print("The Winnner is: ", max_votes_choice)
# delete application
delete_app(algod_client, creator_private_key, app_id)
# clear application from user account
clear_app(algod_client, user_private_key, app_id)
if __name__ == "__main__":
with open("vote_approval.teal", "w") as f:
compiled = compileTeal(approval_program(), mode = Mode.Application, version=2)
f.write(compiled)
with open("vote_clear_state.teal", "w") as f:
compiled = compileTeal(clear_state_program(), mode = Mode.Application, version=2)
f.write(compiled)
main()
please i ask you to help me solve this problem as i really can’t figure out what it could be. Thank you all.