When I specified a normal eoa wallet address(via the transaction inputs and outputs), the funds are sent from the predicate to the addresss and it shows, but doesn’t reflect for a contract address, why is this so, if i am not making a mistake can someone show me how to properly specify that funds should be sent to a contract from a predicate if it evaluates to true.
please urgent !
*This is how i specified the inputs and outputs of the transaction
Hey @shealtielanz, are you trying to transfer funds to a contract using a normal UTXO output?
Smart contracts can’t “receive” UTXOs, funds must be transferred to smart contracts using smart contract “calls”.
If you want your predicate to enforce that some funds are transferred to a smart contract, you will have to have your predicate enforce the transaction script. The predicate can ensure that the script transfers some or all of an asset to the contract.
wow, nice idea.
can you give me a quick code example, or explain how i can use the script to send the funds to a contract.
also amazing repo you had, the gasless-nft was really creative, i got a lot of inspiration from it.
you said the predicate can enforce, the script sends funds via a smart contract call, but i want the predicate to hold the funds, idk i’m honestly confused.
That repo actually has a good example, the gas predicate calls tx_script_bytecode_hash() and checks that the script hash matches a stored hash. And the script in question has some logic.
If you want a predicate to send funds to a contract, you can make a script like this:
script;
fn main(amount: u64) {
let mut coin_amount = 0;
let mut i = 0;
while (i < input_count()) {
if (input_asset(i) ==ASSET_ID) {
coin_amount += input_amount(i);
}
}
transfer(Identity::Contract(CONTRACT_ID), ASSET_ID, coin_amount);
}
And a predicate like this:
predicate;
fn main() {
let script_bytecode_hash: b256 = tx_script_bytecode_hash();
if (script_bytecode_hash != EXPECTED_SCRIPT_HASH) {
return false;
}
return true;
}
Wow, so are you saying that combining them, both, the predicate will allow the script spend it’s funds, sending to to the specified contracts?
can you give me a quick cap of how this is possible on a lower level, so i can easily debug errors if i come across.
also, when writing the tests will i have to specify output::variables, or input::contracts?
how will i have to specify to avoid, incorrect transactions.
Wow, so are you saying that combining them, both, the predicate will allow the script spend it’s funds, sending to to the specified contracts?
Pretty much! Any coins that are included as “inputs” that aren’t immediately spent on “outputs” are available to the script. And the script can transfer them to contracts, to variable outputs, etc. And any coins that aren’t spent in CoinOutputs and aren’t spent in the scripts end up in ChangeOutputs.
I would test the script and the predicate separately: make sure the script transfers funds correctly, and separately make sure the predicate enforces the script.
running 1 test
previous balance of contract: {}
new balance of contract: {0000000000000000000000000000000000000000000000000000000000000000: 5000}
test script_can_transfer ... ok