How to change old implementation contract address on etherscan? - solidity

I wrote upgradable smart contract using solidity and upgraded contract several time.
When I upgraded smart contract, implementation contract address was changed.
But under that address, the old implementation contract address still remains.
https://rinkeby.etherscan.io/address/0x245dBBE31f33569D3d7F1e0df10c93547c44065D#readProxyContract
How to change or hide this old address?

Particularly you can't hide anything once it is stored on the Blockchain. The old address will still be visible.
But if you want that calling to the old contract should fail, you can simply create a self destruct function inside your smart contract and call it when you have updated the smart contract and deployed it with a new address.
Tip -
Always have smart contracts with the self destruct functionality
Whenever you update your smart contract i.e deploy it to a new address, call the self destruct function on the old contract address for it to be destroyed.
Syntax for self destruct -
contract YourContract {
// State variables
// Some functions
function destruct(address addr) ownerOnly {
selfdestruct(addr);
}
// The above function sends all ether from the contract to the specified address
}

Related

Delegating calls to implementation contract solidity

i am using upgradable (proxy) ERC20 contract in my solidity code, and i need to call the functions of that contract in my code, when i initialize the my contract with the address of the proxy, it is not able to access the functions, but when i initialize it with implementation address it works as expected, so what is the proper way to access the implementation contracts functions?
I am thinking saving the proxy contract address and whenever i need to call implementation contracts functions i call implementation function of proxy, then initialize ERC20 implementation with returned address and then call the function with that implementation, but this seems very inefficient if we take gas fees into account. is there more optimal solution?

How can I make smart contract non-upgradeable

Is there a way to make a smart contract NON-upgradeable on Near?
By default I can always overwrite a contract at an account address. This is different from Ethereum where after deployment the contract gets a new address after which it is by default non-upgradeable.
Contract can be locked by removing the full-access key:
https://docs.near.org/develop/deploy#locking-a-contract

How to create solidity function only callable by a wallet address (not a contract)

I want to make sure that my function isn't able to be called programmatically by another smart contract.
Is there a way to create a function in my contract that doesn't allow it to be called by other contracts while still allowing ordinary wallets to call the function?
So, msg.sender returns the address who called your method, and tx.origin returns the address of the account that sent the transaction.
/// #dev Check if method was called by user.
require(msg.sender == tx.origin, "Reverting, Method can only be called directly by user.");

New contracts visibility

first of all, excuse me because I am starting to learn Solidity programming, and this question is surely trivial for most of you, but I haven't found any answer yet.
When I create a simple smart contract from within another one (using "new"), and I try to check the new contract visibility, I cannot find it on etherscan (Rinkeby), even though I can interact with it from within Remix IDE. Is there any reason for that?
Thank you very much in advance!!
First, how do you know which address the new contract has? You can try to log it via event emitting and Remix will show it on the console.
Secondly, on which network are you deploying your contract? By default Remix use an EVM VM that some mimic a fake network, it is not a public test net, just something that runs locally in your browser, meaning, you can not see in etherscan.
To achieve this, you have to choose "injected web3" in the environment dropdown during the deployment process.
There are a lot of gotchas but here is a good guide on how to connect your metamastk testnet.
when you create Contract that Creates other Contracts,It doesn't create or what you are trying to say that it doesn't deploying any
new contract on Rinkeby.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Account {
address public owner;
constructor(address _owner) {
owner = _owner;
}
}
contract AccountFactory{
function createAccount(address _owner) public {
Account account = new Account(_owner);
}
}
When you are deploying the written smart contract both Account and AccountFactory will be deployed you will be able to find it on (Rinkeby)
Therefore each time you hit the public createAccount function it's just making an transaction on with interact with the deployed Account smart contract
which will definitely not create Account smart contract again for each function call.
Have a look HERE
Thank you all!
For example, if this piece of code
SimpleStorage[] public simpleStorageArray;
function createSimpleStorageContract() public {
SimpleStorage simpleStorage = new SimpleStorage();
simpleStorageArray.push(simpleStorage);
}
is suposed to "deploy" a new instance of a contract (storing their addresses in an array), each time I call the function, so we can interact with to store or retrieve values, or whatever, my question came because I figured out that the address of the new "deployed" contract (contained in simpleStorageArray) should be found in Etherscan, but it actually does not.

How do I write proxy and implementation contracts that supports Chainlink functionality (Proxy Pattern via DELEGATECALL Solidity 0.6)

I have a Solidity smart contract which relies on Chainlink oracles for external data that has a lot of functionality code that does not need to be replicated on a per contract basis but does change the state of the contract instance, which is why I decided the proxy pattern using delegate calls makes the most sense. In the proxy pattern I only have to deploy the byte-code for my contracts functions once, and then all other instances of my contract will just delegate call to the implementation contract, and the only new information added to the block chain will be instance fields of that specific contract.
I am able to get an implementation contract deployed and point my deployed proxy to its functions, but then when I call the lock function on the proxy I fail the check require(owner == msg.sender,"Owner only") which doesnt make sense since delegate calls are supposed to pass msg.sender and I set the owner field to msg.sender in the proxy's constructor. If I remove the require, I can call the function without a revert but the locked and debugAddr fields are unchanged, even though the lock function should change them(I thought delegate call was executed in the context of the caller?). Does anyone know what is wrong with my proxy and implementation contracts? I can guess it is to do with memory layouts or the assembly im using to do delegate calls, but I am not yet on the level where I can use my googling skills to find out what is wrong, so if someone can spot where my proxy contract is incorrect/badly formatted please let me know.
Thanks,
Ben
Lock function code snippet
//Locks in the contract, buyer should have already provided data scientist an upload only API key and their model ID
function lock() public returns (bool success)
{
debugAddr = msg.sender;
uint tempStamp = now;
//THIS IS THE REQUIRE THAT FAILS WHEN IT SHOULDNT WHEN I UNCOMMENT THIS AND DEPLOY/RUN
require(msg.sender == owner, "Only owner can lock contract.");
//require(!locked, "Cannot lock contract that is already locked.");
//require(buyer != address(0),"No buyer to lock.");
//require(bytes(buyerModelName).length != 0,"No buyerModelName to lock.");
//require((tempStamp - startTimestamp) < 158400,"Cannot lock contract that was entered by buyer over 44 hours ago.");
//require((getWeekday(tempStamp) == 0) || (getWeekday(tempStamp) == 1 && getHour(tempStamp) < 14),"Contract can only be locked in between Sunday 00:00 UTC and Monday 14:00 UTC");
LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
//require(link.balanceOf(address(this)) >= totalFee, "Contract requires 0.5 LINK total to operate once locked, current LINK balance is under 0.5.");
locked = true;
return true;
}
Proxy contract with require commented(also see the contract's txs, you can see me call lock):
https://kovan.etherscan.io/address/0x1f805d559f6eb7d7b19bf0340db288503f448ae8
Implementation contract the proxy points to:
https://kovan.etherscan.io/address/0xfb41ea6452da396279cbd9d9d8c136121e38fab6
Proxy contract with require uncommented(also see the contract's txs, you can see me call lock, and the revert):
https://kovan.etherscan.io/address/0x2d59aa0c1dd9a77d592167c43f2e65adcb275bfe
Implementation contract the proxy points to:
0x20a1f27d69f7a257741eddaec433642194af0215
Proxy Code and Implementation Code
Referenced Code: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/Proxy.sol
Proxy: https://github.com/benschreyer/Steak/blob/main/SteakQuarterly/ProxyPattern/SteakQuarterlyProxy.sol
Important Note In my proxy I do not want to declare the contract as a ChainlinkClient since then ChainlinkClient's functions will be included in the proxy which is unnecessary as the implementation should have those methods already. Instead I only declare the fields and of ChainlinkClient on my own. I feel like this is a prime place for my implementation to be wrong, but I am not sure what needs to change/if this is even feasible
Implementation: https://github.com/benschreyer/Steak/blob/main/SteakQuarterly/ProxyPattern/SteakQuarterlyDelegate.sol
EDIT: MINIMAL CODE EXAMPLE THAT STILL FAILS
This contract should have the minimal requirements to be a proxy for a ChainlinkClient and only has the lock function and a constructor, I get the same revert on require(owner == msg.sender). If I remove the require, the call to lock on the proxy contract says confirmed, but the proxy's state variables remain unchanged (debugAddr is 0, locked stays false)
Here is the minimal example code(I deployed on remix IDE compiled 0.6.12, the proxy's lock function was called by using at address retrieval with the delegate code compiled so that the abi of the delegate is used): https://github.com/benschreyer/Steak/tree/main/MinimalCodeExample
EDIT 2:
If I remove the ChainlinkClient portion/fields of my proxy and implementation minimum examples as linked above, I get a proxy contract that works and can accept external function calls defined in the implementation contract as it should.
So my question now is how do I write proxy and implementation contract that supports Chainlink GET request functionality? What fields/constants/events/interfaces does my proxy need defined or imported and where should I define/import them to allow for Chainlink to work? For example if I wanted to have my contract retrieve the temperature in Paris from an API via Chainlink, but also be a proxy so that I do not have to redploy all its functions and save on gas price.
Anything I have tried so far(see minimal breaking example) does not work once I add Chainlink into the mix, as I am not sure about how to structure the Proxy contract class so that the storage of the proxy and the access/write of the delegate call to the implementation line up. Here is the minimal code that works after I remove Chainlink functionality:
https://github.com/benschreyer/Steak/tree/main/MinimalCodeExample/WorkingButNoChainlink
A version of my working example proxy/implementation pattern contracts but with Chainlink functionality, or pointers on what fields/events/cosntant the proxy contract needs in order for it to make calls to oracles would be much appreciated.
Instead of defining the fields of ChainlinkClient in your proxy class, write a class ChainlinkClientStorage that holds the fields of ChainlinkClient, then declare your Proxy as inheriting from ChainlinkClientStorage
https://github.com/benschreyer/Steak/blob/main/SteakQuarterly/ProxyPattern/ChainlinkClientStorage.sol
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/Proxy.sol
contract MyProxy is ChainlinkClientStorage, MyContractStorage{}