In this example https://www.ethereum.org/token#full-coin-code i have 2 question.
MyAdvanceToken - why the _transfer method is using > instead of >= for checking require(balanceOf[_from] > _value); while the TokenERC20 in this link is using >= ( require(balanceOf[_from] >= _value);)
Since inheritance will be in development only, the _transfer method base on this example is internal in TokenERC20, is it safe to assume that once deployed no one can use this internal function except from this contract ? There is no other contract that can inherit and use this internal method since inheritance is in development only?
Many thanks in advance
Using > instead of >= is a typo and >= sign should be preferred over >. Imagine you have 15 tokens and want to send all of them - you'll not pass the require with > sign.
It is safe because no one can use once deployed contract to inherit from. To create malignant inheritance you need to use parent contract code in the same or different file and deploy it one more time, creating the second base contract, distinct from the first one and not able to take its tokens.
Related
Has anyone successfully bought from OpenSea utilizing the smart contracts directly?
I am attempting this and have found that:
If you create an order and try to alter any parameter, like so:
let { order, orderHash, value } = await createOrder(
seller,
zone,
offer,
consideration,
0 // FULL_OPEN
);
const basicOrderParameters = getBasicOrderParameters(
0, // EthForERC721
order
);
basicOrderParameters.salt = randomHex(),
The smart contract call to fulfillBasicOrder will revert during the execution of _assertValidSignature(), at the following line:
pop(
staticcall(
gas(),
Ecrecover_precompile, // Call ecrecover precompile.
wordBeforeSignaturePtr, // Use data memory location.
Ecrecover_args_size, // Size of digest, v, r, and s.
0, // Write result to scratch space.
OneWord // Provide size of returned result.
)
)
Therefore, any differing parameter such as startTime or endTime or even salt will generate a different signature -> might be considered an invalid signature, reverting the transaction.
The only ones who can hold the salt for each transaction can be OpenSea, as it is calculated in the backend. timeStart or timeEnd for each order could potentially be an issue as well, but probably scrapeable from external APIs.
This leads to the idea that it might not be possible to reverse an order without access to all parameters used in its creation, such as salt.
On the other hand, this answer says that:
You need to pull the order structure and signature from the Opensea
API, and then just send that order with the buyer's signature (that
you have to prompt) in order to fulfill an order. The process:
Getting the order structure (without the original salt and using arbitrary time) is pretty easy, so why is the transaction always reverting?
EDIT: I don't think the salt, or time is a problem. From the docs:
Calling one of two "standard" functions, fulfillOrder and
fulfillAdvancedOrder, where a second implied order will be constructed with the caller as the offerer, the consideration of the fulfilled order as the offer, and the offer of the fulfilled order as the consideration
This means that orderHashes are necessarily different. One order will have Offer A and Consideration B, and the other order will have Offer B and Consideration A (switching some paramters), which will necessarily generate a different hash and signature for each.
Therefore the salt and time in the signature should not be causing this issue. What could possibly be causing the reversals?
createPair declare in Uniswap Factory contract, addLiquidity declared in Uniswap Router contract, both can create liquidity pair and swap avaliable in app.uniswap.org.
But most developers use addLiquidity instead of createPair. What's the difference between createPair and addLiquidity?
As the function naming suggests, both functions have a different purpose.
createPair() is meant to be used mainly for creating a pair
addLiquidity() is for adding liquidity to a pair
Having said that, addLiquidity() is more robust and performs a call to createPair() if the pair doesn't exist yet. So by calling addLiquidity() you can "create a pair and add liquidity" in one transaction, instead of splitting the action into 2 separate transactions, saving transaction fees.
I was wondering what information are publicly visible and intelligible when an EOA (external ownable address) calls a payable function on a smart contract, with some parameters and a return value.
Let us say I have the smart contract function below, the question is: 'is the return value visible somewhere on the blockchain?'. I am using Solidity 0.8.12.
function askForSecretCode(uint time) external payable returns (bytes32) {
require(msg.value == 42, 'Need to pay 42 wei.');
secretCodes[secretCodesNum] = keccak256(abi.encodePacked(msg.sender, time);
return keccak256(abi.encodePacked(msg.sender, time);
}
Anyone can see the input time param value as a part of a transaction invoking the askForSecretCode function.
Even though if you don't publish the contract source code, the bytecode is public, and there are decompilers that can (with some error rate) help generate source code back from the bytecode. So let's assume that the source code is available as well.
From the source code (or usually even from the pseudocode generated by the decompiler), anyone can determine the storage slot of secretCodesNum (which from the context seems to be a property of the contract) and retrieve its value using the eth_getStorageAt RPC method, including historical values.
Using these secretCodesNum values, they can use the same method to determine storage slots of any secretCodes[secretCodesNum] and their values.
TLDR: Never ever store private data on the blockchain.
I came across this Solidity code:
tx.destination.call.value(tx.value)(tx.data)
but don't understand how it works... especially the tx.data at the end.
This statement is calling a function represented by tx.data on the address at tx.destination passing in wei (tx.value).
To break it down further:
tx.destination is an address. An address has built in members and functions, including call which allows you to execute functions on a contract without the ABI (see Address type definition). For example, you can call a method foobar on a contract without a defined interface like this:
contractAddress.call(bytes4(keccak256("foobar(uint256,uint256)")), val1, val2); // where val1 and val2 are the uint256 parameters to pass in
Using call alone will use some default values when calling the other contract's method. For example, all of the remaining gas will be forwarded. If you want to change those values, you can adjust it by supplying your own gas and/or wei values, which looks like a function call itself:
contractAddress.call.value(9999999)();
This will send 9999999 wei to contractAddress. You can override both the gas and ether sent by chaining multiple function calls:
contractAddress.call.value(99999999).gas(77777)();
The last set of parens in both examples indicate to use the fallback function when sending the wei. You can see a similar example in the Solidity docs FAQ.
If you wanted to call something other than the fallback function, you would combine the 2 examples above, which is what the code you posted is doing. The fact that they are using tx is a bit confusing since that is normally a built-in reference, but they are likely shadowing that and it's referencing a struct with destination, value, and data members.
In the application I am writing I have a Policy class. There are 4 different types of Policy. Each Policy is weighted against the other Policies such that PolicyA > PolicyB > PolicyC > PolicyD.
Who's responsibility is it to implement the logic to determine whether one Policy is greather than another? My initial thought is to overload the > and < operators and implement the logic in the Policy type itself.
Does that violate the SRP?
I would think that a PolicyComparer class should do the evaluation.
I think you are on the right track with the overload however the extension of this is obviously a lot longer
if (A > B || B > C || C > D)
...
You could also store a PolicyWeight attribute in your class, that being a simple built-in type ( int, unsigned int, ... ) which can then be easily compared.
Certianly a dedicated comparer class. If you ever need to provide additional logic (e.g. have two or three different ways of comparing policies), this approach allows you more flexibility (not achievable through operator overloads).
You want a PolicyComparator class. If you want to override < and >, that's fine, but do that overriding in the Policy base class, and have those implementations utilize PolicyComparator to do it.