Using ecrecover function - Solidity - solidity

I'm trying to verify a message, I searched on StackOverflow and I found the ecrecover function. but when I use it, it returns a different address from what I expect.
function verify(bytes32 hash, uint8 v, bytes32 r, bytes32 s) constant returns(address) {
bytes memory prefix = "\x19Ethereum Signed Message:\n32";
bytes32 prefixedHash = keccak256(prefix, hash);
return ecrecover(prefixedHash, v, r, s);
}
signature object:
{
message: 'a',
messageHash: '0x34f291c0b5f0c13c8f43e9d37c04094c22234da43f4040adb36654c98235b4b3',
v: '0x1b',
r: '0x944f8187c19a711259e32dd9ab0f005c97c9e2013c735f823d3ad34c7cd5030f',
s: '0x254607e8d32e8a0436c8d678fe7d3478c8858fd903e164c51f8a8595e723b7a7',
signature: '0x944f8187c19a711259e32dd9ab0f005c97c9e2013c735f823d3ad34c7cd5030f254607e8d32e8a0436c8d678fe7d3478c8858fd903e164c51f8a8595e723b7a71b' }
input: (i pass it to remix-ide)
"0x34f291c0b5f0c13c8f43e9d37c04094c22234da43f4040adb36654c98235b4b3", 0x1b, "0x944f8187c19a711259e32dd9ab0f005c97c9e2013c735f823d3ad34c7cd5030f", "0x254607e8d32e8a0436c8d678fe7d3478c8858fd903e164c51f8a8595e723b7a7"
output: (wrong)
0x5dd277a46b3ab8ce30735d82df5e6e8312bce7ef
Please help me figure out the problems. many thanks.

Related

solidity assert for several not nulls

I have the following function in solidity:
function registerStudentEvaluation(string memory _firstName, string memory _lastName, string memory _subject, uint _note) public returns(Note memory) {
bytes32 studentHash = keccak256(abi.encodePacked(_firstName, _lastName));
bytes32 subjectHash = keccak256(abi.encode(_subject));
address teacherAddress = msg.sender;
assert (students[studentHash] && subjects[subjectHash] && teachers[msg.sender]);
Note memory newNote = Note(studentHash, subjectHash, msg.sender, _note);
bytes32 noteHash = keccak256(abi.encodePacked(studentHash, subjectHash, msg.sender, _note));
notes[noteHash] = newNote;
emit student_evaluated(noteHash);
return newNote;
}
And I am getting these errors:
TypeError: Operator & not compatible with types struct Notes.Student storage ref and struct Notes.Subject storage ref
--> notes.sol:71:17:
|
71 | assert (students[studentHash] & subjects[subjectHash] & teachers[msg.sender])
TypeError: Operator && not compatible with types struct Notes.Student storage ref and struct Notes.Teacher storage ref
TypeError: Invalid type for argument in function call. Invalid implicit conversion from struct Notes.Student storage ref to bool requested.
How can I assert for several not nulls in Solidity?
Solidity uses two ampersands && as the logical AND operator.
assert(true && true);
One ampersand & is the bitwise AND operator.
uint8 three = 3; // 00000011
uint8 five = 5; // 00000101
uint8 result = three & five; // 00000001
Docs: https://docs.soliditylang.org/en/v0.8.12/cheatsheet.html
Solution: Use logical operators in the assert() condition.
assert (students[studentHash] && subjects[subjectHash] && teachers[msg.sender]);
Note: It's not defined in your question but I'm assuming that the students property is defined as mapping(bytes32 => bool) students;

Everscale Solidity. How to work with responsible functions? How to wait for callback?

Free Everscale Solidity. How to work with responsible functions?
How to wait for callback in correct way and check the contract execution result from sdk?
For example I have the contracts (which does nothing userful). How to wait in correct way in my application a writing to a_ and b_ variables?
contract A {
uint256 a_;
string b_;
function foo(uint256 a, string b, address c) extenal {
tvm.accept();
B(c).bar{value: 1 ton, callback: A.callback}(a, b);
}
function callback(uint256 a, string b) external {
tvm.accept();
a_ = a;
b_ = b;
}
}
contract B {
function bar(uint256 a, string b) exrnal responsible returns (uint256, string) {
return { value: 0, bounce: false, flag: 64 } (a, b);
}
}
Well, you can know when the first transaction is completed using wait_for_transaction.
One of the parameters returned by wait_for_transaction is out_messages, a list of all messages created by this transaction. In this case is should be one, the call to callback.
I expect it would be possible to use wait_for_transaction on the these messages.
I haven't tried this though and it is possible wait_for_transaction is only for external messages. In that case maybe using transactions iterator would help instead.

how to use the ECDSA.sol module correctly?

I have this contract using the ECDSA library.
import "./ECDSA.sol";
struct Signature {
uint8 v;
bytes32 r;
bytes32 s;
}
function make(Signature memory sign) public returns(bool)
I try to understand the parameters I have to use in this case. What I can see it's a tuple type value, but I can't figure out what it looks like for v, r, s. Where can I get these values from my address?
The v, r, and s parameters are a result of signing a message with a private key. The signature has 65 bytes, which are split into 3 parts:
65 byte array (of type bytes in Solidity) arranged the following way: [[v (1)], [r (32)], [s (32)]].
Source: OpenZeppelin
Sign off-chain (because you're using a private key).
Note the address in the comment, we'll verify it on-chain later.
const signature = await web3.eth.accounts.sign(
'Hello world',
// below is private key to the address `0x0647EcF0D64F65AdA7991A44cF5E7361fd131643`
'02ed07b6d5f2e29907962d2bfde8f46f03c46e79d5f2ded0b1e0c27fa82f1384'
);
console.log(signature);
Output
{
message: 'Hello world',
messageHash: '0x8144a6fa26be252b86456491fbcd43c1de7e022241845ffea1c3df066f7cfede',
v: '0x1c',
r: '0x285e6fbb504b57dca3ceacc851a7bfa37743c79b5c53fb184f4cc0b10ebff6ad',
s: '0x245f558fa13540029f0ee2dc0bd73264cf04f28ba9c2520ad63ddb1f2e7e9b24',
signature: '0x285e6fbb504b57dca3ceacc851a7bfa37743c79b5c53fb184f4cc0b10ebff6ad245f558fa13540029f0ee2dc0bd73264cf04f28ba9c2520ad63ddb1f2e7e9b241c'
}
Note that v is the last byte of signature, r is the first half, and s is the second half (excluding the last byte).
Verify on-chain
pragma solidity ^0.8;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol";
contract MyContract {
function foo() external pure returns (bool) {
address recovered = ECDSA.recover(
0x8144a6fa26be252b86456491fbcd43c1de7e022241845ffea1c3df066f7cfede, // messageHash
0x1c, // v
0x285e6fbb504b57dca3ceacc851a7bfa37743c79b5c53fb184f4cc0b10ebff6ad, // r
0x245f558fa13540029f0ee2dc0bd73264cf04f28ba9c2520ad63ddb1f2e7e9b24 // s
);
return recovered == address(0x0647EcF0D64F65AdA7991A44cF5E7361fd131643);
}
}

Why does declaring returns type bytes memory give a compiler error?

If we have the following code:
pragma solidity >= 0.5;
contract stringsContract {
function takesTwo(string memory str, uint idx) public pure returns (bytes memory) {
bytes memory bytesStr = bytes(str);
return bytesStr[idx];
}
}
Why do we get TypeError return argument bytes1 is not explicitly convertible to expected type (type of first return variable bytes memory).
The fix was to change bytes memory to bytes:
contract stringsContract {
function takesTwo(string memory str, uint idx) public pure returns (byte) {
bytes memory bytesStr = bytes(str);
return bytesStr[idx];
}
}
Nevertheless, I'm still curious about the reason of the compilation error. Any thoughts?
Variable of type 'bytes' and 'string' are special arrays. In first code snippet you are returning an array which is not yet possible in Solidity yet.
You can find docs: https://solidity.readthedocs.io/en/develop/types.html#bytes-and-strings-as-arrays
When you return in solidity the syntax is like (value_type value_name: optional), what you tried returning bytes which is an array and with name memory, memory itself is spacial keyword in solidity

Static Parameter Function Specialization in D

I've read somewhere that D supports specialization of functions to calls where arguments are compile-time constants. Typical use of this is in matrix power functions (if exponent is 2 x*x is often faster than the general case).
I want this in my member function
bool opIndexAssign(bool b, size_t i) #trusted pure nothrow in {
assert(i < len); // TODO: Add static assert(i < len) when i is constant
} body {
b ? bts(ptr, i) : btr(ptr, i);
return b;
}
of a statically sized BitSet struct I'm writing. This in order to, when possible, get compile-time bounds checking on the index variable i. I thought
bool opIndexAssign(bool b, const size_t i) #trusted pure nothrow in {
static assert(i < len);
} body {
b ? bts(ptr, i) : btr(ptr, i);
return b;
}
would suffice but then DMD complains as follows
dmd -debug -gc -gs -unittest -D -Dd/home/per/.emacs.d/auto-builds/dmd/Debug-Boundscheck-Unittest/home/per/Work/justd/ -w -main ~/Work/justd/bitset.d /home/per/Work/justd/assert_ex.d -of/home/per/.emacs.d/auto-builds/dmd/Debug-Boundscheck-Unittest/home/per/Work/justd/bitset
/home/per/Work/justd/bitset.d(58): Error: bitset.BitSet!2.BitSet.opIndexAssign called with argument types (bool, int) matches both:
/home/per/Work/justd/bitset.d(49): opIndexAssign(bool b, ulong i)
and:
/home/per/Work/justd/bitset.d(65): opIndexAssign(bool b, const(ulong) i)
/home/per/Work/justd/bitset.d(66): Error: variable i cannot be read at compile time
/home/per/Work/justd/bitset.d(66): while evaluating: static assert(i < 2LU)
/home/per/Work/justd/bitset.d(58): Error: bitset.BitSet!2.BitSet.opIndexAssign called with argument types (bool, int) matches both:
/home/per/Work/justd/bitset.d(49): opIndexAssign(bool b, ulong i)
Do I have to make parameter i a template parameter, say using type U, and then use static if someTypeTrait!U. I tried this but isMutable!Index always evaluates to true.
import std.traits: isIntegral;
bool opIndexAssign(Index)(bool b, Index i) #trusted pure nothrow if (isIntegral!Index) in {
import std.traits: isMutable;
// See also: http://stackoverflow.com/questions/19906516/static-parameter-function-specialization-in-d
static if (isMutable!Index) {
assert(i < len);
} else {
import std.conv: to;
static assert(i < len,
"Index " ~ to!string(i) ~ " must be smaller than BitSet length " ~ to!string(len));
}
} body {
b ? bts(ptr, i) : btr(ptr, i);
return b;
}
What you're trying to do doesn't really work. You can do a template value parameter:
void foo(int i)() { /* use i at compile time */ }
but then you can't pass a runtime value to it, and it has different call syntax: foo!2 vs foo(2).
The closest you can get is is CTFE:
int foo(int i) { return i; }
enum something = foo(2); // works, evaluated at compile time
int s = foo(2); // also works, but runs at runtime.
Inside the function, there is a magic if(__ctfe) { running at compile time } else { at runtime}, but again, this isn't if there's a literal, it is if the function is run in a CT context, e.g., assigning the result to an enum constant.
But, otherwise, an int literal is still a mutable int as far as the function is concerned. So what you're specifically trying to do won't work in D as it is right now. (There's been some talk about wanting a way to tell if it is a literal, but as far as I know, there's no plan to actually do it.)