I want to check my assumptions on things that I didn't fully understand during the deployment of the Gnosis Safe contracts on an EVM-based chain.
I would appreciate it if you could help me verify my assumptions about the deployment.
Three steps below are needed to complete the Safe deployment.
Make a request for a new deployment at https://github.com/safe-global/safe-singleton-factory.
Deploy the Safe contracts on a custom network.
Add the newly supported network to the safe-deployments repository located at https://github.com/safe-global/safe-deployments.
The purpose of the first step is to employ a deterministic deployment proxy which allows the contracts' addresses to be predetermined.
The second step requires having coins from the custom network, and this is the only purpose for adding the MNEMONIC to the .env file.
Format of the MNEMONIC variable in the .env file is:
MNEMONIC="antique assume recycle glance agent habit penalty forum behave danger crop weekend"
The only purpose of including ETHERSCAN_API_KEY in .env is to update the Safe contracts code on the Etherscan.
Below is something that I cannot even begin to guess the purpose of:
What is the purpose of the third step? Is the purpose of this to document the deployments of the custom networks?
You got it right. Adding your deployment to that repository will inform everyone that your chain has the Gnosis Safe singleton contract.
This repository is associated with an npm package, which the Gnosis Safe SDK depends on. This means that after adding your network, the SDK will be able to deploy and use contracts form your chain.
The Uniswap router contract has a few methods ending in *SupportingFeeOnTransferTokens, e.g. swapExactTokensForETHSupportingFeeOnTransferTokens.
https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/UniswapV2Router02.sol
I vaguely (think I) understand that these methods are supposed to be called for swapping tokens that somehow take a tax/rake during transfers.
I have a few questions regarding these:
In a nutshell, what is the difference in behavior for these functions different from the regular swap functions? Do they somehow interact with the minOut parameters?
How does the Dex UI know which method to call? How does it know the SupportingFee version needs to be called instead of the standard swap?
What happens if my web3 script calls the wrong version of the method? Failures? Wrong amounts out?
I have a question about versioning of smart contracts in Ethereum. Lots of articles have been written about how to decouple your logic and data, how to use interfaces when referencing other contracts, how to use generic key value stores to store data and retrieving it through library functions in a strongly typed way.
What about querying transactions and event log from old versions of the smart contract? Transactions and emitted events cannot be migrated. They are immutable. And perhaps you need to keep track of them in the client app for history. Events can be added, removed or have their signature changed in different contract versions. How do you deal with querying and decoding transaction input and event data for multiple versions of a contract?
Each event in Solidity is internally represented by a hash of its signature. Functions are also presented by the hash.
let encodedFunctionSignature = web3.eth.abi.encodeFunctionSignature('sendMessage(string,address)');
console.log(encodedFunctionSignature);
// => 0xc48d6d5e
The signatuare is first 32 bytes of keccak256 hash taken over by the function signature string, spaces removed.
If the event signature changes, the hash changes as well and you can distinct different ABIs for events.
Then you just need to have the matching version of ABI file to decode the event to human readable symbolic form.
For example, what does it mean in this quote?
Integrating with an external API is almost a guarantee in any modern web app. To effectively test such integration, you need to stub it out. A good stub should be easy to create and consistently up-to-date with actual, current API responses. In this post, we’ll outline a testing strategy using stubs for an external API.
A stub is a controllable replacement for an Existing Dependency (or collaborator)
in the system. By using a stub, you can test your code without
dealing with the dependency directly.
External Dependency - Existing Dependency:
It is an object in your system that your code
under test interacts with and over which you have no control. (Common
examples are filesystems, threads, memory, time, and so on.)
Forexample in below code:
public void Analyze(string filename)
{
if(filename.Length>8)
{
try
{
errorService.LogError("long file entered named:" + filename);
}
catch (Exception e)
{
mailService.SendEMail("admin#hotmail.com", "ErrorOnWebService", "someerror");
}
}
}
You want to test mailService.SendEMail() method, but to do that you need to simulate an Exception in your test method, so you just need to create a Fake Stub errorService object to simulate the result you want, then your test code will be able to test mailService.SendEMail() method. As you see you need to simulate a result which is from an another Dependency which is ErrorService class object (Existing Dependency object).
A stub, in this context, means a mock implementation.
That is, a simple, fake implementation that conforms to the interface and is to be used for testing.
Layman's terms, it's dummy data (or fake data, test data...etc.) that you can use to test or develop your code against until you (or the other party) is ready to present/receive real data. It's a programmer's "Lorem Ipsum".
Employee database not ready? Make up a simple one with Jane Doe, John Doe...etc.
API not ready? Make up a fake one by creating a static .json file containing fake data.
In this context, the word "stub" is used in place of "mock", but for the sake of clarity and precision, the author should have used "mock", because "mock" is a sort of stub, but for testing. To avoid further confusion, we need to define what a stub is.
In the general context, a stub is a piece of program (typically a function or an object) that encapsulates the complexity of invoking another program (usually located on another machine, VM, or process - but not always, it can also be a local object). Because the actual program to invoke is usually not located on the same memory space, invoking it requires many operations such as addressing, performing the actual remote invocation, marshalling/serializing the data/arguments to be passed (and same with the potential result), maybe even dealing with authentication/security, and so on. Note that in some contexts, stubs are also called proxies (such as dynamic proxies in Java).
A mock is a very specific and restrictive kind of stub, because a mock is a replacement of another function or object for testing. In practice we often use mocks as local programs (functions or objects) to replace a remote program in the test environment. In any case, the mock may simulate the actual behaviour of the replaced program in a restricted context.
Most famous kinds of stubs are obviously for distributed programming, when needing to invoke remote procedures (RPC) or remote objects (RMI, CORBA). Most distributed programming frameworks/libraries automate the generation of stubs so that you don't have to write them manually. Stubs can be generated from an interface definition, written with IDL for instance (but you can also use any language to define interfaces).
Typically, in RPC, RMI, CORBA, and so on, one distinguishes client-side stubs, which mostly take care of marshaling/serializing the arguments and performing the remote invocation, and server-side stubs, which mostly take care of unmarshaling/deserializing the arguments and actually execute the remote function/method. Obviously, client stubs are located on the client side, while sever stubs (often called skeletons) are located on the server side.
Writing good efficient and generic stubs becomes quite challenging when dealing with object references. Most distributed object frameworks such as RMI and CORBA deal with distributed objects references, but that's something most programmers avoid in REST environments for instance. Typically, in REST environments, JavaScript programmers make simple stub functions to encapsulate the AJAX invocations (object serialization being supported by JSON.parse and JSON.stringify). The Swagger Codegen project provides an extensive support for automatically generating REST stubs in various languages.
Stub is a function definition that has correct function name, the correct number of parameters and produces dummy result of the correct type.
It helps to write the test and serves as a kind of scaffolding to make it possible to run the examples even before the function design is complete
This phrase is almost certainly an analogy with a phase in house construction — "stubbing out" plumbing. During construction, while the walls are still open, the rough plumbing is put in. This is necessary for the construction to continue. Then, when everything around it is ready enough, one comes back and adds faucets and toilets and the actual end-product stuff. (See for example How to Install a Plumbing Stub-Out.)
When you "stub out" a function in programming, you build enough of it to work around (for testing or for writing other code). Then, you come back later and replace it with the full implementation.
You have also a very good testing frameworks to create such a stub.
One of my preferrable is Mockito There is also EasyMock and others... But Mockito is great you should read it - very elegant and powerfull package
RPC Stubs
Basically, a client-side stub is a procedure that looks to the client as if it were a callable server procedure.
A server-side stub looks to the server as if it's a calling client.
The client program thinks it is calling the server; in fact, it's calling the client stub.
The server program thinks it's called by the client; in fact, it's called by the server stub.
The stubs send messages to each other to make the RPC happen.
Source
"Stubbing-out a function means you'll write only enough to show that the function was called, leaving the details for later when you have more time."
From: SAMS Teach yourself C++, Jesse Liberty and Bradley Jones
Stub is a piece of code which converts the parameters during RPC (Remote procedure call).The parameters of RPC have to be converted because both client and server use different address space. Stub performs this conversion so that server perceive the RPC as a local function call.
A stub can be said as a fake substitute of the original function, which gives output, which is not accessible right now because of reasons:
It is not developed right now
It is not callable from the current environment (maybe testing)
A stub has :
Exact number of parameters
Exact output format (not necessarily correct output)
Why a stub is used?
When function is not accessible in an environment such as testing, or when its implementation is not available.
Example:
let's say you want to test a function in which there's a network call. While testing the code, you cannot wait for a network call's result for your test. so you write a mock output of the network call and proceed with your test.
TestFunction(){
// Some things here
// Some things here
var result = networkCall(param)
// something depending on the result
}
This networkCall gives out lets say a string, so you have to create a function with exact same parameters and it should give string output.
String fakeNetworkCall(int param){
if(param == 1) return "OK";
else return "NOT OK";
}
Now you have written a fake function, use this as replacement in your code
TestFunction(){
// Some things here
// Some things here
var result = fakeNetworkCall(param)
// something depending on the result
}
This fakeNetworkCall is a stub.