For example, I have a function
function addClaimers(ClaimItemImport[] claimItems) onlyOwner external
and the ClaimItemImport struct looks as follows:
struct ClaimItemImport {
uint128 balance;
uint256 claimAddress;
}
How to call it from tondev with parameters?
This does not work:
tondev contract run Contract.abi.json --address XYZ addClaimers -i claimItems:[[123, 0x123], [456, 0x456]]
--address 0:540c1837656674d548c934258ddec9b5fd11b543da977b0016c14b5650bc7eb5 \
--input '{ "point": { "color": "red", "center": { "x": 1, "y": 2 } } }'
Check readme in the end of this section https://github.com/tonlabs/tondev#run-contract-deployed-on-the-network
I've updated my tondev + used the following syntax:
tondev contract run FidosafeDAO.abi.json addClaimers --address 0:2540afc97408aec8e094eaf2695acd8fd4c301830590214be584e4b627e5bf90 -i '{"claimItems":[{"balance":0,"claimAddress":0}]}'
Related
need help to get the correct funcID. I've Tried many ways. Will be glad to get your help.
Thanks!
slugSha256() {
slug=$(echo -n "$1" | sha256sum | cut -d' ' -f1)
echo -n $((16#"${slug:0:8}"))
}
functionHash() {
hash=$(slugSha256 "$(echo -n "$1" | sed 's/ //g')")
if [[ "$1" == *constructor* ]]; then hash=$((hash ^ (2 ** 31))); fi
printf '0x%x' "$hash"
}
functionID() { functionHash "$1v2"; }
`
functionID "main()(string)" # 0xb0992770
functionID "redeem(uint256, string, uint256)()" # 0x58160fa0
functionID "constructor()()" # 0x68b55f3f
foo.sol
pragma ever-solidity >= 0.64.0;
contract foo {
constructor() public {}
function main() public returns (string) {}
function redeem(uint256 a, string b, uint256 c) public {}
}
via everdev npx everdev sol update
~/.everdev/solidity/solc --function-ids foo.sol
via sold:
sold --function-ids foo.sol
out:
{
"constructor": "0x68b55f3f",
"main": "0x30992770",
"redeem": "0x58160fa0"
}
via web tool https://ever.bytie.moe/serializer
For the constructor, you need to clear the highest bit to get the correct funcID
In this case, if there was an opportunity to use await, then there would be no reason to create a question, but await is not recommended to be used in contracts:
Note: This feature was designed to be used in debots, in usual contracts use it at your own risk. https://github.com/tonlabs/TON-Solidity-Compiler/blob/master/API.md#synchronous-calls
Pong.sol
pragma ton-solidity ^0.51.0;
contract Pong {
function get(uint b) external responsible returns (uint) {
return b + 1;
}
}
Ping.sol
pragma ton-solidity ^0.51.0;
interface IPong {
function get(uint b) external responsible returns (uint);
}
contract Ping {
uint public result;
uint public tmp;
function run(address pong, uint a) public view returns(uint) {
update(pong, a);
tvm.accept();
return a + tmp;
}
function update(address pong, uint a) internal pure {
IPong(pong).get{callback: Ping.onGet}(a);
}
function onGet(uint b) external {
tvm.accept();
tmp = b;
}
}
Run.bash
#!/usr/bin/env bash
set -o errexit
tondev se reset
rm -fr *.abi.json *.tvc
# Deploy Pong Contract
tondev sol compile Pong.sol
tondev contract deploy Pong --value 1000000000
pongAddress=$(tondev contract info Pong | grep Address | cut -d':' -f3 | cut -d' ' -f1)
echo "$pongAddress"
# Deploy Ping Contract
tondev sol compile Ping.sol
tondev contract deploy Ping --value 1000000000
pingAddress=$(tondev contract info Ping | grep Address | cut -d':' -f3 | cut -d' ' -f1)
echo "$pingAddress"
# Run
tondev contract run Ping run --input "pong:$pongAddress,a:1" | grep value0
# value0:0x0000000000000000000000000000000000000000000000000000000000000001
tondev contract run Ping run --input "pong:$pongAddress,a:1" | grep value0
# value0:0x0000000000000000000000000000000000000000000000000000000000000003
The purpose of the question is to understand how to get the value 3 on the first request, if possible. If not, then a more extensive explanation of how to develop contracts in the conditions of an asynchronous blockchain.
You can do this in asynchronous style more simply (without callback and await).
I changed the code of your contracts:
pragma ton-solidity ^0.51.0;
interface IPing {
function onGet(uint b) external;
}
contract Pong {
function get(uint b) external {
IPing(msg.sender).onGet(b + 1);
}
}
pragma ton-solidity ^0.51.0;
interface IPong {
function get(uint b) external;
}
contract Ping {
uint public tmp;
function run(address pong, uint a) public {
IPong(pong).get(a);
tvm.accept();
tmp = a + tmp;
}
function onGet(uint b) external {
tvm.accept();
tmp = b + tmp;
}
}
Now call a little changed this Run.bash
#!/usr/bin/env bash
set -o errexit
tondev se reset
tondev network default se
rm -fr *.abi.json *.tvc
# Deploy Pong Contract
tondev sol compile Pong.sol
tondev contract deploy Pong --value 1000000000
pongAddress=$(tondev contract info Pong | grep Address | cut -d':' -f3 | cut -d' ' -f1)
echo "$pongAddress"
# Deploy Ping Contract
tondev sol compile Ping.sol
tondev contract deploy Ping --value 1000000000
pingAddress=$(tondev contract info Ping | grep Address | cut -d':' -f3 | cut -d' ' -f1)
echo "$pingAddress"
# Run
tondev contract run Ping run --input "pong:$pongAddress,a:1" &> /dev/null
tondev contract run-local Ping tmp | grep tmp
# tmp:0x0000000000000000000000000000000000000000000000000000000000000003
tondev contract run Ping run --input "pong:$pongAddress,a:1" &> /dev/null
tondev contract run-local Ping tmp | grep tmp
# tmp:0x0000000000000000000000000000000000000000000000000000000000000006
A bit of my philosophy, why it is better:
the contracts must works without waiting. So callbacks and awaits, it is not good.
Callbacks are very useful in debots, and it can take place there because debots running on your device. But it is another story…
I run programs all the time from the command line that allow your to mix the order of the parameters. And they catch you if you throw something extra into the mix. For example:
$xxx -r abc -q def -w xyz
$xxx -w xyz -q def -r abc
How are they doing this? Is there some module for this?
Here is an example using Getopt::Long:
use v6;
use Getopt::Long;
my %opt = help => False, 'r=s' => "", 'q=s' => "", 'w=s' => "";
my %options = get-options(%opt).hash;
say %options;
say #*ARGS;
Example run:
$ p.p6 -w xyz -q def -r abc hello
{help => False, q => def, r => abc, w => xyz}
[hello]
Use the MAIN sub:
#!/usr/bin/env raku
use v6;
sub MAIN(:$these ="These", :$are="Are", :$params="Params") {
say "$these $are $params";
}
You can type these parameters in any order:
./command-line.p6 --are=well --these=those
those well Params
And will also catch any extra parameter, showing you the actual parameters:
./command-line.p6 --are=well --these=those --not=this_one
Usage:
./command-line.p6 [--these=<Any>] [--are=<Any>] [--params=<Any>]
If you are only interested in parameters with a single dash, you'll need GetOpt::Long as indicated by Hakon
I am trying to ping some ip addresses in my router. I use this code:
for {set n 0} {$n < 10} {incr n} {puts [exec "ping 199.99.$n.1]}
but this will show the output.
the issue is that I don't want to see the output. I would like to send that output into another variable and the search the content of variable with "regexp" and get the result, and do the rest of the story.
but I don't know how I can do that.
Use the set command. The puts command prints it's argument.
set pingOutput [exec ping "199.99.$n.1"]
Or append if you want all IP's results in one variable.
set allPingOutput ""
for {set n 0} {$n < 10} {incr n} {
append allPingOutput [exec ping "199.99.$n.1"]
}
Try calling the ping with the -c flag:
ping -c 1 10.0.1.1
Not sure how to do it in tcl but in php for example:
It is very important to use ping -c1 <IP address> , otherwise the script will never end as the ping process never ends :)
My code uses an array of results of every IP
for {set i 2 } {$i < 10} {incr i} {
catch {if {[regexp {bytes from} [exec ping -c1 192.168.12.$i]]} {
set flag "reachable"
} else { set flag "not reachable"}
set result(192.168.12.$i) $flag
}
}
parray result
OUTPUT :
result(192.168.12.2) = reachable
result(192.168.12.3) = reachable
result(192.168.12.5) = reachable
result(192.168.12.6) = reachable
result(192.168.12.7) = reachable
result(192.168.12.9) = reachable
Instead of storing and manipulating , I used regexp .
I have an AWK script which looks like
#!/usr/bin/gawk -f
BEGIN { print myVar; }
{ print; }
which I can run locally in a Unix shell via the command
./myScript.awk -v myVar=value /tmp/inputfile
It correctly prints "value" and then dumps the inputfile.
I set up an apache web server with CGI enabled and created the following myScript.cgi:
#!/usr/bin/gawk -f
BEGIN {
print "Content-type: text/plain";
print "";
print myVar;
}
{ print; }
I can run it by pointing my web browser to
http://localhost/cgi-bin/myScript.cgi?/tmp/inputfile
but how can I pass the "-v myVar=value" bit through the URL?
You cannot pass a '-v' variable through the CGI interface. The only way to access information is via a number number of environment variables that the CGI interface sets for you. You can access these in awk through the ENVIRON array. You are probably mostly interested in the QUERY_STRING variable, so try this:
#!/usr/bin/gawk -f
BEGIN {
print "Content-type: text/plain"
print ""
print ENVIRON["QUERY_STRING"]
}
1
When accessed as http://localhost/cgi-bin/myScript.cgi?myVar=foo&otherVar=bar, ENVIRON["QUERY_STRING"] will contain myVar=foo&otherVar=bar. You will have to process this string yourself to extract your variables. For example (untested):
BEGIN {
split(ENVIRON["QUERY_STRING"], a, "&")
for (i in a) {
if (a[i] ~ /^myVar=/) {
split(a[i], tmp, "=")
myVar=tmp[2]
}
}
}