How to get funID? - solidity

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

Related

How to get the value 3 on the first request without await?

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…

Recursive file includes

I'm writing an awk script to include sourced files in a shell script recursively:
$ cat build.awk
function slurp(line) {
if ( line ~ /^\. / || line ~ /^source / ) {
split(line, words)
while ( (getline _line < words[2]) > 0 ) {
slurp(_line)
}
} else if ( NR != 1 && line ~ /^#!/ ) {
# Ignore shebang not in the first line
} else {
print line
}
}
{
slurp($0)
}
For example, with the following four shell scripts,
$ for i in a b c d; do cat $i.sh; echo; done
#!/bin/sh
echo this is a
. b.sh
#!/bin/sh
echo this is b
. c.sh
. d.sh
#!/bin/sh
echo this is c
#!/bin/sh
echo this is d
I expect that by running awk -f build.awk a.sh I get
#!/bin/sh
echo this is a
echo this is b
echo this is c
echo this is d
However, the actual result is
#!/bin/sh
echo this is a
echo this is b
echo this is c
d.sh is not included. How can I fix this? What is my mistake?
Aha, that was because in awk, variables have no lexical scope! I am too noob for the awk language. The following works:
$ cat build.awk
function slurp(line, words) {
if ( line ~ /^\. / || line ~ /^source / ) {
split(line, words)
while ( (getline _line < words[2]) > 0 ) {
slurp(_line)
}
} else if ( NR != 1 && line ~ /^#!/ ) {
# Ignore shebang not in the first line
} else {
print line
}
}
{
slurp($0)
}
$ awk -f build.awk a.sh
#!/bin/sh
echo this is a
echo this is b
echo this is c
echo this is d

SSH - Seperate grep results with a title

I have 3 grep runs and results send to my email:
((grep -irl 'abc' /usr/www/users/FTPUSERNAME/*) && (grep -irl 'xyz' /usr/www/users/FTPUSERNAME/*) && (grep -irl 'xXx' /usr/www/users/FTPUSERNAME/*)) | mail me#mywebsite.com
However this creates a combined list of all files.
Is there a way to separate the results by inserting a title to each grep
So the email I get looks something like this:
Title for files with abc
/Path-To-File/filename.php
/Path-To-File/filename.php
/Path-To-File/filename.php
Title for files with xyz
/Path-To-File/filename.php
/Path-To-File/filename.php
/Path-To-File/filename.php
Title for files with xXx
/Path-To-File/filename.php
/Path-To-File/filename.php
Thanks for the help,
Amit
FWIW I wouldn't do 3 separate greps just for that and I also wouldn't use grep to find files when there's a tool with a very obvious name for that (find), e.g. with GNU awk for IGNORECASE and true multi-dimensional arrays:
find /usr/www/users/FTPUSERNAME/ -type f -exec awk '
BEGIN {
IGNORECASE = 1
split("abc xyz xXx",res)
}
{
for (i in res) {
re = res[i]
if ($0 ~ re) {
hits[re][FILENAME]
}
}
}
END {
for (i=1; i in res; i++) {
re = res[i]
printf "Title for files with %s\n", re
for (file in hits[re]) {
print file
}
print ""
}
}
' {} + |
mail ...
Note that given the above if you need to add a 4th regexp you just add it to the split() call, it only searches for files once instead of 3 times, you're only opening each found file once instead of 3 times, and you can format the output of the search however you like. There's various ways it could be optimized for speed if necessary.
You should be able to achieve this by pre-pending each of your grep commands with an echo. Here is your command slightly modified :
$ ((echo "Title for files with abc" && grep -irl 'abc' /usr/www/users/FTPUSERNAME/*) && ( echo "Title for files with xyz" && grep -irl 'xyz' /usr/www/users/FTPUSERNAME/*) && ( echo "Title for files with xXx" && grep -irl 'xXx' /usr/www/users/FTPUSERNAME/*)) | mail me#mywebsite.com

How can sed replace but skip the replaced characters in the pipeline?

I'm looking to escape some character ( and ), their respective escape codes are (40) and (41).
echo 'Hello (world)' | sed 's/(/(40)/g;s/)/(41)/g'
This code fails with Hello (40(41)world(41) because it will also process the output from the first replacement. Is there any way I can skip the replacement characters or do conditional branches here. I don't want to use a temporary (as the input sequence could contain anything).
All you need is:
$ echo 'Hello (world)' | sed 's/(/(40\n/g; s/)/(41)/g; s/\n/)/g'
Hello (40)world(41)
The above is safe because \n can't be present in the input since sed reads one line at a time. With some seds you might need to use a backslash followed by a literal newline or $'\n' instead of just \n.
Given the answer you posted, though, this may be what you really want (uses GNU awk for ord(), multi-char RS, and RT):
$ cat tst.awk
#load "ordchr"
BEGIN { RS = "[][(){}]"; ORS="" }
{ print $0 ( RT=="" ? "" : "(" ord(RT) ")" ) }
$ echo 'Hello (world) foo [bar] other {stuff} etc.' | awk -f tst.awk
Hello (40)world(41) foo (91)bar(93) other (123)stuff(125) etc.
If you have an older gawk that doesn't support #load than get a new one but if that's impossible for some reason then just create an array of the values, e.g.:
$ cat tst.awk
BEGIN {
RS = "[][(){}]"
ORS = ""
for (i=0;i<=255;i++) {
char = sprintf("%c",i)
map[char] = "(" i ")"
}
}
{ print $0 ( RT=="" ? "" : map[RT] ) }
$ echo 'Hello (world) foo [bar] other {stuff} etc.' | awk -f tst.awk
Hello (40)world(41) foo (91)bar(93) other (123)stuff(125) etc.
EDIT: timing data
Given a file that has these 10 lines:
$ head -10 file1m
When (chapman) billies leave [the] street, And drouthy {neibors}, neibors, meet;
As market days are wearing late, And folk begin to [tak] the gate,
While (we) sit bousing {at} the nappy, An' getting [fou] and unco happy,
We think na on the [lang] Scots (miles), The mosses, {waters}, slaps and stiles,
That lie between us and our hame, Where sits our sulky, sullen dame,
Gathering her [brows] like gathering storm, (Nursing) her wrath to keep it warm.
This truth fand honest Tam o' Shanter,
As he frae Ayr ae night did canter:
(Auld Ayr, wham ne'er a town surpasses,
For honest men and bonie lasses).
repeating to a total of 1 million lines, 10.5 million characters, 60.4 million bytes:
$ wc file1m
1000000 10500000 60400000 file1m
the 3rd-run timing stats for the sed script and both awk scripts above are:
$ time sed 's/(/(40\n/g; s/)/(41)/g; s/\n/)/g; s/\[/(91)/g; s/\]/(93)/g; s/{/(123)/g; s/}/(125)/g;' file1m > sed.out
real 0m7.488s
user 0m7.378s
sys 0m0.093s
$ cat function.awk
#load "ordchr"
BEGIN { RS = "[][(){}]"; ORS="" }
{ print $0 ( RT=="" ? "" : "(" ord(RT) ")" ) }
$ time awk -f function.awk file1m > awk_function.out
real 0m7.426s
user 0m7.269s
sys 0m0.155s
$ cat array.awk
BEGIN {
RS = "[][(){}]"
ORS = ""
for (i=0;i<=255;i++) {
char = sprintf("%c",i)
map[char] = "(" i ")"
}
}
{ print $0 ( RT=="" ? "" : map[RT] ) }
$ time awk -f array.awk file1m > awk_array.out
real 0m4.758s
user 0m4.648s
sys 0m0.092s
I verified that all 3 scripts produce the same, successfully modified output:
$ head -10 sed.out
When (40)chapman(41) billies leave (91)the(93) street, And drouthy (123)neibors(125), neibors, meet;
As market days are wearing late, And folk begin to (91)tak(93) the gate,
While (40)we(41) sit bousing (123)at(125) the nappy, An' getting (91)fou(93) and unco happy,
We think na on the (91)lang(93) Scots (40)miles(41), The mosses, (123)waters(125), slaps and stiles,
That lie between us and our hame, Where sits our sulky, sullen dame,
Gathering her (91)brows(93) like gathering storm, (40)Nursing(41) her wrath to keep it warm.
This truth fand honest Tam o' Shanter,
As he frae Ayr ae night did canter:
(40)Auld Ayr, wham ne'er a town surpasses,
For honest men and bonie lasses(41).
$ wc sed.out
1000000 10500000 68800000 sed.out
$ diff sed.out awk_function.out
$ diff sed.out awk_array.out
$
The problem is solved by creating an ord function in awk. It doesn't appear sed has this functionality.
#! /bin/sh
awk '
BEGIN { _ord_init() }
function _ord_init(low, high, i, t) {
low = sprintf("%c", 7) # BEL is ascii 7
if (low == "\a") {
low = 0;
high = 127;
} else if (sprintf("%c", 128 + 7) == "\a") {
low = 128;
high = 255;
} else {
low = 0;
high = 255;
}
for (i = low; i <= high; i++) {
t = sprintf("%c", i);
_ord_[t] = i;
}
}
function ord(str, c) {
c = substr(str, 1, 1)
return _ord_[c]
}
// {
split($0, array, "\\[|\\]|\\(|\\)|\\{|\\}", separators);
len = length(array);
seplen = length(separators);
for (i = 1; i < len; ++i) {
printf "%s(%s)", array[i], ord(separators[i]);
}
printf "%s", array[len];
}
'
You can do this in perl, which supports one-liners and look-behind in regular expressions. Simply require the close-paren not be part of an existing escape:
$ echo 'Hello (world)' | perl -pe 's/\(/(40)/g; s/(?<!\(40)\)/(41)/g'
Hello (40)world(41)
It's tricky in sed but easy in any language with associative arrays.
perl -pe 'BEGIN { %h = ("(" => "(40)", ")" => "(41)" );
$r = join("|", map { quotemeta } keys %h); }
s/($r)/$h{$1}/g'

AWK - execute string as command?

This command prints:
$ echo "123456789" | awk '{ print substr ($1,1,4) }'
1234
Is it possible to execute a string as command? For example, this command:
echo "123456789" | awk '{a="substr"; print a ($1,1,4) }'
Result:
$ echo "123456789" | awk '{a="substr"; print a ($1,1,4) }'
awk: {a="substr"; print a ($1,1,4) }
awk: ^ syntax error
EDIT:
$ cat tst.awk
function my_substr(x,y,z) { return substr(x,y,z) }
{ a="my_substr"; print #a($1,1,4) }
bolek#bolek-desktop:~/Pulpit$ echo "123456789" | gawk -f tst.awk
gawk: tst.awk:3: { a="my_substr"; print #a($1,1,4) }
gawk: tst.awk:3: ^ nieprawidłowy znak '#' w wyrażeniu
bolek#bolek-desktop:~/Pulpit$
I don't think it is possible to do that in awk directly, but you can get a similar effect by using the shell. Recall that the awk program is given as a string, and strings are concatenated in the shell just by writing them next to one another. Thus, you can do this:
a=substr
echo "123456789" | awk '{ print '"$a"'($1, 1, 4) }'
resulting in 1234.
You can call user-defined functions via variables in GNU awk using indirect function calls, see http://www.gnu.org/software/gawk/manual/gawk.html#Indirect-Calls
$ cat tst.awk
function foo() { print "foo() called" }
function bar() { print "bar() called" }
BEGIN {
the_func = "foo"
#the_func()
the_func = "bar"
#the_func()
}
$ gawk -f tst.awk
foo() called
bar() called
Unfortunately due to internal implementation issues, if you want to call builtin functions that way then you need to write a wrapper for each:
$ cat tst.awk
function my_substr(x,y,z) { return substr(x,y,z) }
{ a="my_substr"; print #a($1,1,4) }
$ echo "123456789" | gawk -f tst.awk
1234