Difference between this 2 values? - solidity

In my js file I call a send transaction to the smart contract, so what is the difference between values :
instance.multiply.sendTransaction(val,{ from: accounts[0], gas : 300000} and instance.multiply.sendTransaction({ from: accounts[0], gas : 30000, value : val},
I am passing first one to the function as an argument and the second is accessible in the function just by msg.value ?

In your first code snippet, you're passing val as an argument to a function.
In the second code snippet, you're not passing any arguments, but you're sending val wei in the transaction. Yes, the contract, can see how much wei was sent by looking at msg.value, but importantly there was also a transfer of ether. (10**18 wei == 1 ether.)
So the key differences between the two are:
One passes a value as an argument, and the other doesn't.
One sends some ether with the transaction, and the other doesn't.

Proper Syntax for web3.eth.sendTransaction
web3.eth.sendTransaction(transactionObject [, callback])
Second one works fine instance.multiply.sendTransaction({ from: accounts[0], gas : 30000, value : val}, and should.
The format of sendTransaction is sendTransaction({from: eth.accounts[0], data: code, gas: 100000}).
from: String - The address for the sending account. Uses the
web3.eth.defaultAccount property, if not specified.
to: String - (optional) The destination address of the message,
left undefined for a contract-creation transaction.
value: Number|String|BigNumber - (optional) The value transferred
for the transaction in Wei, also the endowment if it's a
contract-creation transaction.
gas: Number|String|BigNumber - (optional, default:
To-Be-Determined) The amount of gas to use for the transaction
(unused gas is refunded).
data: String - (optional) Either a byte string containing the
associated data of the message, or in the case of a
contract-creation transaction, the initialisation code.
For more See: https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethsendtransaction

Related

Solidity -- using uninitialized storage pointers safely

I'm trying to gas-optimize the following solidity function by allowing users to sort the array they pass in such a way that I can perform less storage reads. However, to do this I need to use an uninitialized storage pointer -- which the compiler doesnt let me do (^0.8.0). How can I safely use an uninitialized storage pointer and have it be accepted by the compiler?
function safeBatchReleaseCollaterals(
uint256[] memory bondIds,
uint256[] memory collateralIds,
address to
) public {
// 'memoization' variables
uint256 lastAuthorizedBond = 2**256 - 1;
uint256 lastCurrencyRef = 2**256 - 1;
Currency storage currency;
for (uint256 i = 0; i < bondIds.length; i++) {
uint256 bondId = bondIds[i];
// check if we authorized this bond previously?
if (lastAuthorizedBond != bondId) {
require( // expensive check. Reads 2 slots!!
_isAuthorizedToReleaseCollateral(bondId, msg.sender),
"CollateralManager: unauthorized to release collateral"
);
lastAuthorizedBond = bondId;
}
uint256 collateralId = collateralIds[i];
Collateral storage c = collateral[bondId][collateralId];
// check if we read this Currency previously?
if (lastCurrencyRef != c.currencyRef) {
currency = currencies[c.currencyRef]; // expensive 1 slot read
lastCurrencyRef = c.currencyRef;
}
_transferGenericCurrency(currency, address(this), to, c.amountOrId, "");
emit CollateralReleased(bondId, collateralId, to);
}
}
As a quick explanation of the structure: this is similar to a batch erc1155 transfer, except I'm storing a lot of data related to the transaction in some slots under the Currency and Collateral and Bond objects. Since the reads can get intensive, I want to optimize gas by caching reads. Since having an actual cache map is also expensive, I instead optimize by caching only the previous list item, and rely on the user to sort the array in such a way that results in the smallest gas costs.
The lastAuthorizedBond variable caches which bondId was last authorized -- if it repeats, we can cut out an expensive 2-slot read! (which results in maybe 16% gas savings during tests. You can see, significant). I tried doing something similar with the currency read, storing the lastCurrencyRef and hoping to store the actual result of the read into the currency variable. The compiler complains about this however, and maybe justly so.
Is there a way to pass this by the compiler? Do I just have to ditch this optimization? Though nobody is allowed to register the 2**256-1 currency or bond, is this code even safe?
Note that the collateral entry gets deleted after this runs -- cannot double release.

nand2tetris HDL: Getting error "Sub bus of an internal node may not be used"

I am trying to make a 10-bit adder/subtractor. Right now, the logic works as intended. However, I am trying to set all bits to 0 iff there is overflow. To do this, I need to pass the output (tempOut) through a 10-bit Mux, but in doing so, am getting an error.
Here is the chip:
/**
* Adds or Subtracts two 10-bit values.
* Both inputs a and b are in SIGNED 2s complement format
* when sub == 0, the chip performs add i.e. out=a+b
* when sub == 1, the chip performs subtract i.e. out=a-b
* carry reflects the overflow calculated for 10-bit add/subtract in 2s complement
*/
CHIP AddSub10 {
IN a[10], b[10], sub;
OUT out[10],carry;
PARTS:
// If sub == 1, subtraction, else addition
// First RCA4
Not4(in=b[0..3], out=notB03);
Mux4(a=b[0..3], b=notB03, sel=sub, out=MuxOneOut);
RCA4(a=a[0..3], b=MuxOneOut, cin=sub, sum=tempOut[0..3], cout=cout03);
// Second RCA4
Not4(in=b[4..7], out=notB47);
Mux4(a=b[4..7], b=notB47, sel=sub, out=MuxTwoOut);
RCA4(a=a[4..7], b=MuxTwoOut, cin=cout03, sum=tempOut[4..7], cout=cout47);
// Third RCA4
Not4(in[0..1]=b[8..9], out=notB89);
Mux4(a[0..1]=b[8..9], b=notB89, sel=sub, out=MuxThreeOut);
RCA4(a[0..1]=a[8..9], b=MuxThreeOut, cin=cout47, sum[0..1]=tempOut[8..9], sum[0]=tempA, sum[1]=tempB, sum[2]=carry);
// FIXME, intended to solve overflow/underflow
Xor(a=tempA, b=tempB, out=overflow);
Mux10(a=tempOut, b=false, sel=overflow, out=out);
}
Instead of x[a..b]=tempOut[c..d] you need to use the form x[a..b]=tempVariableAtoB (creating a new internal bus) and combine these buses in your Mux10:
Mux10(a[0..3]=temp0to3, a[4..7]=temp4to7, ... );
Without knowing what line the compiler is complaining about, it is difficult to diagnose the problem. However, my best guess is that you can't use an arbitrary internal bus like tempOut because the compiler doesn't know how big it is when it first runs into it.
The compiler knows the size of the IN and OUT elements, and it knows the size of the inputs and outputs of a component. But it can't tell how big tempOut would be without parsing everything, and that's probably outside the scope of the compiler design.
I would suggest you refactor so that each RCA4 has a discrete output bus (ie: sum1, sum2, sum3). You can then use them and their individual bits as needed in the Xor and Mux10.

How to avoid call-stack attack in the case of absence of EIP-150?

While before EIP-150, could we avoid the call-stack attack by checking return value, of low-level functions .send(), .call(), .delegatecall() and .staticcall(), whether is false or not?
For example (msg.sender is a contract):
...
msg.sender.send(amount);
...
changing to:
...
if(!msg.sender.send(amount)) revert Error("Call failed!");
...
Whole contract in:
https://hackernoon.com/smart-contract-attacks-part-2-ponzi-games-gone-wrong-d5a8b1a98dd8
I found the answer: Nope. Because, in this attack, call-stack slots are filled before execution reaches return of calling contract.
A way of preventing could be calculating expected amount of required gas for called function; setting the gas amount of calling function with respect to this.

Specify the (posiible) change address in sendmany bitcoin rpc call?

bitcoin sendmany api will add a change address if there is no combination of utxos that match the amount+fee.
How do i set the change address?
What is the default for change address?
Docs for reference:
sendmany "" {"address":amount} ( minconf "comment" ["address",...] replaceable conf_target "estimate_mode" )
Send multiple times. Amounts are double-precision floating point numbers.
Arguments:
1. dummy (string, required) Must be set to "" for backwards compatibility.
2. amounts (json object, required) A json object with addresses and amounts
{
"address": amount, (numeric or string, required) The bitcoin address is the key, the numeric amount (can be string) in BTC is the value
}
3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.
4. comment (string, optional) A comment
5. subtractfeefrom (json array, optional) A json array with addresses.
The fee will be equally deducted from the amount of each selected address.
Those recipients will receive less bitcoins than you enter in their corresponding amount field.
If no addresses are specified here, the sender pays the fee.
[
"address", (string) Subtract fee from this address
...
]
6. replaceable (boolean, optional, default=fallback to wallet's default) Allow this transaction to be replaced by a transaction with higher fees via BIP 125
7. conf_target (numeric, optional, default=fallback to wallet's default) Confirmation target (in blocks)
8. estimate_mode (string, optional, default=UNSET) The fee estimate mode, must be one of:
"UNSET"
"ECONOMICAL"
"CONSERVATIVE"
Result:
"txid" (string) The transaction id for the send. Only 1 transaction is created regardless of
the number of addresses.
Technically you always pay the fee, default bitcoin core commands generate a new address automatically on each transaction. If you want to specify a change adress you should use createRawTransaction instead.

Ragel: avoid redundant call of "when" clause function

I'm writing Ragel machine for rather simple binary protocol, and what I present here is even more simplified version, without any error recovery whatsoever, just to demonstrate the problem I'm trying to solve.
So, the message to be parsed here looks like this:
<1 byte: length> <$length bytes: user data> <1 byte: checksum>
Machine looks as follows:
%%{
machine my_machine;
write data;
alphtype unsigned char;
}%%
%%{
action message_reset {
/* TODO */
data_received = 0;
}
action got_len {
len = fc;
}
action got_data_byte {
/* TODO */
}
action message_received {
/* TODO */
}
action is_waiting_for_data {
(data_received++ < len);
}
action is_checksum_correct {
1/*TODO*/
}
len = (any);
fmt_separate_len = (0x80 any);
data = (any);
checksum = (any);
message =
(
# first byte: length of the data
(len #got_len)
# user data
(data when is_waiting_for_data #got_data_byte )*
# place higher priority on the previous machine (i.e. data)
<:
# last byte: checksum
(checksum when is_checksum_correct #message_received)
) >to(message_reset)
;
main := (msg_start: message)*;
# Initialize and execute.
write init;
write exec;
}%%
As you see, first we receive 1 byte that represents length; then we receive data bytes until we receive needed amount of bytes (the check is done by is_waiting_for_data), and when we receive next (extra) byte, we check whether it is a correct checksum (by is_checksum_correct). If it is, machine is going to wait for next message; otherwise, this particular machine stalls (I haven't included any error recovery here on purpose, in order to simplify diagram).
The diagram of it looks like this:
$ ragel -Vp ./msg.rl | dot -Tpng -o msg.png
Click to see image
As you see, in state 1, while we receiving user data, conditions are as follows:
0..255(is_waiting_for_data, !is_checksum_correct),
0..255(is_waiting_for_data, is_checksum_correct)
So on every data byte it redundantly calls is_checksum_correct, although the result doesn't matter at all.
The condition should be as simple: 0..255(is_waiting_for_data)
How to achieve that?
How is is_checksum_correct supposed to work? The when condition happens before the checksum is read, according to what you posted. My suggestion would be to check the checksum inside message_received and handle any error there. That way, you can get rid of the second when and the problem would no longer exist.
It looks like semantic conditions are a relatively new feature in Ragel, and while they look really useful, maybe they're not quite mature enough yet if you want optimal code.