I tried to write a small teal program that accepts one argument that if you cube it and it equals 8, pays you out any balance that’s in the escrow contract.
This for sure isn’t right – when I compiled it, I got the error * arg 0 wanted type uint64 got []byte
This is the program – is this sort of on the right track?
// in pseudocode, i want:
// function(a) { if (a^3 == 8) { CloseRemainderTo callerOfFunction } }
arg 0
*
arg 0
*
arg 0
==
int 8
// if a * a * a == 8 send txn to address caller
&&
txn Fee
int 1000000
txn CloseRemainderTo
Sender
Your ordering is off. So if you want to cube and check it should look something like:
//note this has no error checking and protection. If you want to use it, please make sure to add //appropriate checks for fees, closeremainder, and round ranges
int 3
int 3
*
int 3
*
int 27
==
Escrow Contract Account
You can compile it something like:
goal clerk compile cube.teal
you can then write out a transaction to a file to test it like:
clerk send -F cube.teal -t BVTBSJRACDKBEBPQAEVBVYKG4DDAFO7YTQWPF4ND7SIKGZDLKNG4RAJC4U -a 10000 -o cube.stxn -d ~/node/betanetdata
note that if you drop the -o parameter it will send to the network. With the o parameter you can see how the TEAL code is evaluated by doing:
goal clerk dryrun -d ~/node/betanetdata -t cube.stxn
outputs:
tx[0] cost=8 trace:
1 intcblock =>
5 intc_0 => 3 0x3
6 intc_0 => 3 0x3
7 * => 9 0x9
8 intc_0 => 3 0x3
9 * => 27 0x1b
10 intc_1 => 27 0x1b
11 == => 1 0x1
Here is where I am at now – I have this program that will take in three variables a b and c and if a^3 + b^3 + c^3 == 42 then it will send the account balance to the address that called the program correctly.
Here is the teal program:
// in pseudocode, i want:
// function(a, b, c) { if (a^3 * b^3 * c^3 == 42) { CloseRemainderTo callerOfFunction } }
// a cubed
int 80538738812075974
int 80538738812075974
*
int 80538738812075974
*
// b cubed
int 12602123297335631
int 12602123297335631
*
int 12602123297335631
*
// c cubed
int 80435758145817515
int 80435758145817515
*
int 80435758145817515
*
// c cubed + b cubed - a cubed (since a is a negative number needs to be subtracted not added)
intc_0
intc_1
+
intc_2
-
// does it equal 42, if yes send account balance to sender
==
int 42
When I run it, I get a valid transaction at the end but no funds are released from the escrow contract to my address, does that mean my program is returning false?
you need to create an lsig and also use signLogicSigTransaction function like:
LogicsigSignature lsig = new LogicsigSignature(program, null);
System.out.println("Escrow address: " + lsig.toAddress().toString());
Transaction tx = new Transaction(lsig.toAddress(), new Address(DEST_ADDR), BigInteger.valueOf(1000), amount, firstRound, lastRound, genId, genesisHash);
// send the transaction to the network
try {
// if this was a delegation operation
// the lsig object would contian the signature
SignedTransaction stx = Account.signLogicsigTransaction(lsig, tx);
// Msgpack encode the signed transaction
byte[] encodedTxBytes = Encoder.encodeToMsgPack(stx);
TransactionID id = algodApiInstance.rawTransaction(encodedTxBytes);
System.out.println("Successfully sent tx with id: " + id);
} catch (ApiException e) {
// This is generally expected, but should give us an informative error message.
System.err.println("Exception when calling algod#rawTransaction: " + e.getResponseBody());
}
I pulled this function name from the docs - is this not right? let lsig = algosdk.makeLogicSig(program) TypeError: algosdk.makeLogicSig is not a function
javascript file currently looks like this - it’s pulled from the example with the logic sig lines pulled back in:
const algosdk = require('algosdk');
require('dotenv').config()
//Retrieve the token, server and port values for your installation in the algod.net
//and algod.token files within the data directory
const token = { 'X-API-Key': process.env.PURESTAKE_API_KEY, 'Content-Type': 'application/x-binary' }
const server = "https://betanet-algorand.api.purestake.io/ps1"
const port = ""
//Recover the account
var recoveredAccount = algosdk.mnemonicToSecretKey(process.env.ALGORAND_MNEMONIC);
console.log(recoveredAccount.addr);
//check to see if account is valid
var isValid = algosdk.isValidAddress(recoveredAccount.addr);
console.log("Is this a valid address: " + isValid);
//instantiate the algod wrapper
let algodclient = new algosdk.Algod(token, server, port);
//submit the transaction
(async() => {
//Get the relevant params from the algod
let params = await algodclient.getTransactionParams();
let endRound = params.lastRound + parseInt(1000);
let fee = await algodclient.suggestedFee();
// move the TEAL program into Uint8Array
let program = new Uint8Array(Buffer.from("ASADAQIGIiILIgsiIgsiCyMjCyMLIiMJJAkSJA==", "base64"));
// makeLogicSig method takes the program and parameters
// in this example we have no parameters
// If we did have parameters you would add them like
// let args = [
// Uint8Array.from("123"),
// Uint8Array.from("456")
// ];
// And remember TEAL parameters are order specific
let lsig = algosdk.makeLogicSig(program);
console.log("Escrow address: " + lsig.toAddress().toString());
// sign the logic with your accounts secret
// key. This is essentially giving your
// key authority to anyone with the lsig
// and if the logic returns true
// exercise extreme care
// If this were an escrow account usage
// you would not do this sign operation
// lsig.sign(recoveredAccount.sk);
// At this point you can save the lsig off and share
// as your delegated signature.
// The LogicSig class supports serialization and
// provides the lsig.toByte and fromByte methods
// to easily convert for file saving and
// reconstituting and LogicSig object
let txn = {
"from": recoveredAccount.addr,
"to": lsig.toAddress(),
"fee": params.fee,
"amount": 0,
"firstRound": params.lastRound,
"lastRound": endRound,
"genesisID": params.genesisID,
"genesisHash": params.genesishashb64
};
// create logic signed transaction.
// Had this been an escrow the lsig would not contain the
// signature but would be submitted the same way
let rawSignedTxn = algosdk.signTransaction(txn, recoveredAccount.sk);
//Submit the lsig signed transaction
let tx = (await algodclient.sendRawTransaction(rawSignedTxn.blob));
console.log("Transaction : " + tx.txId);
})().catch(e => {
console.log('error', e);
});
Here is where we are at - would be very cool to get it all working today so we can launch it potentially Monday to celebrate the mainnet launch:
I am using this script to invoke the teal escrow contract program:
This is the script
const algosdk = require('algosdk');
require('dotenv').config()
//Retrieve the token, server and port values for your installation in the algod.net
//and algod.token files within the data directory
const token = { 'X-API-Key': process.env.PURESTAKE_API_KEY, 'Content-Type': 'application/x-binary' }
const server = "https://betanet-algorand.api.purestake.io/ps1"
const port = ""
//Recover the account
var recoveredAccount = algosdk.mnemonicToSecretKey(process.env.ALGORAND_MNEMONIC);
console.log(recoveredAccount.addr);
//check to see if account is valid
var isValid = algosdk.isValidAddress(recoveredAccount.addr);
console.log("Is this a valid address: " + isValid);
//instantiate the algod wrapper
let algodclient = new algosdk.Algod(token, server, port);
//submit the transaction
(async() => {
//Get the relevant params from the algod
let params = await algodclient.getTransactionParams();
let endRound = params.lastRound + parseInt(1000);
let fee = await algodclient.suggestedFee();
// move the TEAL program into Uint8Array
let program = new Uint8Array(Buffer.from("ASADAQIGIiILIgsiIgsiCyMjCyMLIiMJJAkSJA==", "base64"));
// makeLogicSig method takes the program and parameters
// in this example we have no parameters
// If we did have parameters you would add them like
// let args = [
// Uint8Array.from("123"),
// Uint8Array.from("456")
// ];
// And remember TEAL parameters are order specific
let lsig = algosdk.makeLogicSig(program);
// sign the logic with your accounts secret
// key. This is essentially giving your
// key authority to anyone with the lsig
// and if the logic returns true
// exercise extreme care
// If this were an escrow account usage
// you would not do this sign operation
// lsig.sign(recoveredAccount.sk);
// At this point you can save the lsig off and share
// as your delegated signature.
// The LogicSig class supports serialization and
// provides the lsig.toByte and fromByte methods
// to easily convert for file saving and
// reconstituting and LogicSig object
let txn = {
"from": recoveredAccount.addr,
"to": "VH3FY2SRG3347JN7T4E6OKMPHZYME2NT4PXXOYDQ3LK6W6E45WZDABMB6U",
"fee": params.fee,
"amount": 0,
"firstRound": params.lastRound,
"lastRound": endRound,
"genesisID": params.genesisID,
"genesisHash": params.genesishashb64
};
// create logic signed transaction.
// Had this been an escrow the lsig would not contain the
// signature but would be submitted the same way
let rawSignedTxn = algosdk.signTransaction(txn, recoveredAccount.sk);
//Submit the lsig signed transaction
let tx = (await algodclient.sendRawTransaction(rawSignedTxn.blob));
console.log("Transaction : " + tx.txId);
})().catch(e => {
console.log('error', e);
});
The teal program is:
// in pseudocode, i want:
// function(a, b, c) { if (a^3 * b^3 * c^3 == 42) { CloseRemainderTo callerOfFunction } }
// a cubed
int 1
int 1
*
int 1
*
// b cubed
int 1
int 1
*
int 1
*
// c cubed
int 2
int 2
*
int 2
*
// c cubed + b cubed - a cubed (since a is a negative number needs to be subtracted not added)
intc_0
intc_1
-
intc_2
-
// does it equal 42, if yes send txn to sender
==
int 6
And after I run the javascript, the transaction on betanet is:
TMMANDAD36TXUJA5UOEZHVFVVL3KZVHLCCHXYVQGFFN4LFULBJ6A
And I expected it to output true and then send the fund balance to the sender’s address, but no funds are sent from the escrow contract to the sender.
I tried to just make a simple contract that adds one and two and if that equals three send the account balance to the sender. But after I call it, there is still a balance in the escrow contract. What am I missing?
int 1
int 2
+
==
int 3
&&
txn CloseRemainderTo
txn Sender