node
node copied to clipboard
Use invokeExternalContract to do a token transfer
Describe the bug I created a smartcontract to act as escrow for betting. I do this :
Object[] params = new Object[] { owner, amount };
System.out.println("send token to "+owner+", "+amount);
Object result = invokeExternalContract("GcqTxR4qjHfzmcYGaMeGi7T1fPf414oKzfTjUjAFKuPB", "transfer", params);
Also smartcontract was deployed with these options :
@UsingContract(address = "GcqTxR4qjHfzmcYGaMeGi7T1fPf414oKzfTjUjAFKuPB", method = "transfer") in smartcontract before the method i use to call invokeExternalContract
also tried at deployment and execution from client side to specify usedSmartContractsByte with GcqTxR4qjHfzmcYGaMeGi7T1fPf414oKzfTjUjAFKuPB . used like this in client code :
SmartContractInvocationData scData = new SmartContractInvocationData(smartContractDeployData, method,
params, usedSmartContractsByte, false);
When I try this method I had : com.credits.client.node.exception.NodeClientException: Credits Node error: state is empty!
from node smartcontract executor issue seems to be located there : https://github.com/CREDITSCOM/ewa/blob/master/sc-api/src/main/java/com/credits/scapi/v0/SmartContract.java#L94 smart contract "GcqTxR4qjHfzmcYGaMeGi7T1fPf414oKzfTjUjAFKuPB" can't be modify
if (!usedContract.getContractData().isStateCanModify() && !Arrays.equals(
usedContract.getContractData().getContractState(),
returnValue.newContractState)) {
throw new ContractExecutorException("smart contract \"" + contractAddress + "\" can't be modify");
}
I didn t manage to get the error on my node but with previous version I remember the problem seems to be located there :
To Reproduce Here is the initiator wallet I used : https://monitor.credits.com/testnet-r4_2/account/Eyh6ZBiM9D9yyLDwFG7nqAwgm8fFfJn7NauZ6bQxsufn#
here is the smartcontract : https://monitor.credits.com/testnet-r4_2/Contract/5LKBpWvcDXYi4QK9xpx9Mraibj6hqgoai9R6m2Hn1qV3
** Additional question ** Can we transfer token to a smartcontract address ? If so, how can we initiate token transfer token from this same smartcontract as it can t be initiator ?
I've been trying this feature myself and I'm experiencing similar issues as @micmac0
My token contract is: https://monitor.credits.com/testnet-r4_2/contract/6vNF6KMXHqj6UtHgSVYKyf24v4KMRXDC5TzpiMkMUihB
After that I created a simple contract that calls the transfer
function via invokeExternalContract
(https://monitor.credits.com/testnet-r4_2/Contract/uLesZgD5Hq7RzMwzEEJk1p38MiQTkGaKJvKMg9jpini)
import com.credits.scapi.annotations.*;
import com.credits.scapi.v0.*;
public class simpleContract extends SmartContract {
public simpleContract() {
}
@UsingContract(address = "6vNF6KMXHqj6UtHgSVYKyf24v4KMRXDC5TzpiMkMUihB", method = "transfer")
public void getValue(String wallet, String tosend) {
Object[] params = new Object[] { wallet, tosend };
Object returnValue = invokeExternalContract("6vNF6KMXHqj6UtHgSVYKyf24v4KMRXDC5TzpiMkMUihB", "transfer", params);
System.out.println(returnValue);
}
}
Using a similar contract calling the balanceOf
function does show success
on the monitor. Using the transfer
method gives me errors in the contract-executor log which I'll attach to this post.
Caused by: exception.ContractExecutorException: smart contract "6vNF6KMXHqj6UtHgSVYKyf24v4KMRXDC5TzpiMkMUihB" can't be modify
at com.credits.scapi.v0.SmartContract.invokeExternalContract(SmartContract.java:94)
executor-log-2019-06-12copy.txt
Edit: as the error mentioned that I can not modify the contract, I tried to retrieve the decimal
value via the invokeExternalContract
function. As the getDecimal() function does not modify the contract. This worked fine.
Version 417 The new version seems to behave quite differently but still do not work. Here is an exemple of transaction : https://monitor.credits.com/testnet-r4_2/transaction/79fba823c5480ee5fd9ab65f3987f8ba4743c203b1f37cbeeed2925fc1007ea2.1
I call a business method "addNewBet" and this one call token smartcontract to do a transfer. I got a success status code (with 416 was a failed) on client side but :
- I don t see transaction with token smartcontract on monitor.
- initiator token are not decreased on monitor and target don t get token
- no trace of transfer in token history
- when i request balanceOf from client i see no change in wallets.
and logs I got from one of my node :
16-06-2019 23:58:20.505 [ pool-4-thread-5] DEBUG com.credits.thrift.ContractExecutorHandler - <-- executeByteCode
accessId=111
initiatorAddress=Eyh6ZBiM9D9yyLDwFG7nqAwgm8fFfJn7NauZ6bQxsufn invokedContract=SmartContractBinary(contractAddress:EA 9F AD 04 80 14 4D DC AF 12 28 5B C6 57 05 50 FA 77 9D EE ED D5 2A 56 62 90 50 C8 30 8A 1B 66, object:ClassObject(byteCodeObjects:[ByteCodeObject(name:smart.BetMatchTemplate, byteCode:CA FE BA BE 00 00 00 37 01 62 07 00 B3 0A 00 53 00 B4 08 00 91 09 00 4F 00 B5 08 00 B6 09 00 4F 00 B7 08 00 B8 09 00 4F 00 B9 09 00 4F 00 BA 09 00 4F 00 BB 07 00 BC 0A 00 0B 00 B4 09 00 4F 00 BD 09 00 4F 00 BE 0B 00 36 00 BF 09 00 4F 00 C0 09 00 4F 00 C1 09 00 4F 00 C2 0A 00 C3 00 C4 09 00 4F 00 C5 09 00 4F 00 C6 09 00 4F 00 C7 09 00 4F 00 C8 08 00 C9 09 00 4F 00 CA 08 00 CB 09 00...)], instance:AC ED 00 05 73 72 00 16 73 6D 61 72 74 2E 42 65 74 4D 61 74 63 68 54 65 6D 70 6C 61 74 65 B6 17 B3 B0 B4 9C A4 59 02 00 14 4C 00 04 62 65 74 73 74 00 0F 4C 6A 61 76 61 2F 75 74 69 6C 2F 4D 61 70 3B 4C 00 16 63 6F 6D 6D 75 6E 69 74 79 45 73 63 72 6F 77 41 64 64 72 65 73 73 74 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2
F 53 74 72 69 6E 67 3B 4C 00 13 63 6F 6D 6D 75 6E 69 74 79 46 65 65 50...), stateCanModify:true)
methodHeaders=[MethodHeader(methodName:addNewBet, params:[<Variant v_int:0>, <Variant v_string:50>])]
executionTime=60000 version=1
16-06-2019 23:58:20.510 [ pool-4-thread-5] DEBUG com.credits.utils.ContractExecutorServiceUtils - casted param[0] = 0 16-06-2019 23:58:20.510 [ pool-4-thread-5] DEBUG com.credits.utils.ContractExecutorServiceUtils - casted param[1] = 50 16-06-2019 23:58:20.510 [ pool-4-thread-5] DEBUG com.credits.utils.StopWatch - isThreadCpuTimeEnabled=true, start measurement 0
send token to EJmvMuYdZABi8NK7okWP1m273qbqGNeK6wCGc5Bg3X2L, 50
16-06-2019 23:58:20.512 [ pool-2-thread-2] DEBUG com.credits.service.node.apiexec.NodeApiExecInteractionServiceImpl - getExternalSmartContractByteCode: ---> accessId = 111; addressBase58
= Axbxj5oKyDjJg1rtcDNmnxmK36EDHtWA6wQjDDUjxgkF
16-06-2019 23:58:20.513 [ pool-2-thread-2] DEBUG com.credits.service.node.apiexec.NodeApiExecInteractionServiceImpl - getExternalSmartContractByteCode: <--- result = SmartContractGetResu
ltData{byteCodeObjects=[ByteCodeObjectData{name='smart.TokenTBT1', byteCode=[-54, -2, -70, -66, 0, 0, 0, .............. ............ ...............], stateCanModify=true}
16-06-2019 23:58:20.515 [2op6ES2pc6j2cnTSj261] DEBUG com.credits.utils.ContractExecutorServiceUtils - casted param[0] = EJmvMuYdZABi8NK7okWP1m273qbqGNeK6wCGc5Bg3X2L
16-06-2019 23:58:20.515 [2op6ES2pc6j2cnTSj261] DEBUG com.credits.utils.ContractExecutorServiceUtils - casted param[1] = 50
16-06-2019 23:58:20.515 [2op6ES2pc6j2cnTSj261] DEBUG com.credits.utils.StopWatch - isThreadCpuTimeEnabled=true, start measurement 0
16-06-2019 23:58:20.516 [2op6ES2pc6j2cnTSj261] DEBUG com.credits.utils.StopWatch - stop measurement 0 spentTime=0
result AAAAAAAAAAAAAAAAAA = true
Token transfer ok add bet to 0
init bet to Eyh6ZBiM9D9yyLDwFG7nqAwgm8fFfJn7NauZ6bQxsufn, 50.000000
total bet for Eyh6ZBiM9D9yyLDwFG7nqAwgm8fFfJn7NauZ6bQxsufn 50.000000
16-06-2019 23:58:20.518 [ pool-4-thread-5] DEBUG com.credits.utils.StopWatch - stop measurement 0 spentTime=0
16-06-2019 23:58:20.518 [ pool-4-thread-5] DEBUG com.credits.thrift.ContractExecutorHandler - --> ExecuteByteCodeResult(status:APIResponse(code:0, message:success), results:[SetterMethodResult(status:APIResponse(code:0, message:success), invokedContractState:AC ED 00 05 73 72 00 16 73 6D 61 72 74 2E 42 65 74 4D 61 74 63 68 54 65 6D 70 6C 61 74 65 B6 17 B3 B0 B4 9C A4 59 02 00 14 4C 00 04 62 65 74 73 74 00 0F 4C 6A 61 76 61 2F 75 74 69 6C 2F 4D 61 70 3B 4C 00 16 63 6F 6D 6D 75 6E 69 74 79 45 73 63 72 6F 77 41 64 64 72 65 73 73 74 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 4C 00 13 63 6F 6D 6D 75 6E 69 74 79 46 65 65 50..., ret_val:<Variant v_boolean:true>, executionCost:0)], externalContractsState:{})