create a new contract in solidity - solidity

I have a called contract, and a calling contract. The calling contract needs to create the called contract on the fly. It should be easy to do by
CalledContract c = new CalledContract()
in your solidity code. However, the complication is that the called contract also uses a library, and the trufflesuite will complain that the library needs to be linked before I can create a new called contract on the fly in the calling contract body.

Have you specified the link before you run migrations and deploy the contracts?
something like below?
// 3 files
contractA.sol
contractB.sol
library.sol
// your migration file, #_something.js
import "contractA.sol";
import "contractB.sol";
import "library.sol";
module.exports = function(deployer) {
deployer.deploy(library_name);
deployer.autolink();
deployer.deploy(contractA);
deployer.deploy(contractB);
};

Related

Get pool balances from BalancerV2 in Solidity

I am trying to inspect the pool balances of a decentralized exchange called Balancer. The implementation is done with the main version V2.
I want to get the pool balance with
vault.getPoolTokens(0x5c6ee304399dbdb9c8ef030ab642b10820db8f56000200000000000000000014);
The contract looks like this:
contract BalancerV2 {
IVault private constant vault = "0xBA12222222228d8Ba445958a75a0704d566BF2C8";
function getPoolTokens() public view returns(uint) {
return vault.getPoolTokens(0x5c6ee304399dbdb9c8ef030ab642b10820db8f56000200000000000000000014);
}
}
But it gives me the following error message:
from solidity:
contracts/BalancerV2.sol:8:37: TypeError: Type literal_string "0xBA12222222228d8Ba445958a75a0704d566BF2C8" is not implicitly convertible to expected type contract IVault.
IVault private constant vault = "0xBA12222222228d8Ba445958a75a0704d566BF2C8";
^------------------------------------------^
My question is:
How is it possible that even in the official GitHub repository they have a working example of how to initialize the vault with solidity compiler version 0.7.0 and I'm literally trying the same with getting this error?
By the way, the example in the documentation has a typo so it won't compile. Just in case if someone from the devs sees this.
https://dev.balancer.fi/resources/pool-interfacing#pool-balances
I am trying to compile this contract and am expecting to get this result:
tokens: [0xba100000625a3754423978a60c9317c58a424e3D,
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2]
balances: [5720903090084350251216632,
7939247003721636150710]
Instead of:
IVault private constant vault = "0xBA12222222228d8Ba445958a75a0704d566BF2C8";
try this:
IVault private constant vault = IVault(0xBA12222222228d8Ba445958a75a0704d566BF2C8);

Python architecture, correct way to pass configurable initialization object to project modules

I have a big architecture question about how to pass set of configurable / replaceable objects to modules of my project?
For example the set may be a bot, logger, database, etc.
Currently I'm just importing they, it make a big problem when you want to replace them during a tests.
Lets' say import app.bot will hard to test and patch
I had tried a multiple solutions but failed with them:
Option 1:
Create some base class with which will accepts set of such objects (db, bot, etc).
Every logic class (who need this set) will inherit this class.
AFAIK the similar approach there in SqlAlchemy ORM.
So the code will looks like:
app.config.py:
Class Config:
db: DB
...
tests.py:
import app.config
Config.db = Mock()
create_app.py:
import app.config
def create_app(db):
app.config.Config.db = db
logic.py
import app.config
User(app.config.Config):
def handle_text(text):
self.db.save_text(text=text)
...
The problem with this case is that most likely you can't importing as from app.config import Config
because it will lead to wrong behavior and this is implicit restriction.
Option 2
Pass this set in __init__ arguments to every instance.
(It's ma be a problem if app has many classes, > 20 like in my app).
User:
def __init__(..., config: ProductionConfig):
...
Option 3
In many backend frameworks (flask for example) there are context object.
Well we can inject our config into this context during initialization.
usage.py:
my_handler(update, context):
context.user.handle_text(text=update.text, db=context.db)
The problem with this approach is that every time we need to pass context to access a database in our logic.
Option 4
Create config by condition and import it directly.
This solution may be bad because conditions increases code complexity.
I'm following rule "namespace preferable over conditions".
app.config.py:
db = get_test_db() if DEBUG else get_production_db()
bot = Mock() if DEBUG else get_production_bot()
P.S. this question isn't "opinion based" because in some point the wrong solutions will leads to bad design and bugs therefore.

Verifying a Contract on BSCScan.com

I created a cryptocurrency with the help of a friend of mine (it took us ages to copy-paste codes from here and there) and to edit the contract's info, which is crucial for me, I now need to verify the contract. Here's my contract address:
0xe1c7a0d5e099a1f0c14b60b0c320423cf2f4543b
and here is the code I used in Remix:
pragma solidity >=0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";
contract HelpingArtistsAtRisk is ERC20 {
constructor(uint256 initialsupply) public ERC20 ("Helping Artists At Risk", "HAAR"){
_mint(msg.sender,initialsupply);}
}
It gives me error after error when I try to verify it. Here are the error messages:
Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: " to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.
--> myc
ParserError: Source "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol" not found: File import callback not supported
--> myc:3:1:
|
3 | import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol"
BEP-20.sol:1:1: Error: Compiler version >=0.8.0 does not satisfy the r semver requirement
ParserError: Expected pragma, import directive or contract/interface/library/struct/enum/constant/function definition.
--> myc:1:1:
|
1 | "SPDX-License-Identifier: UNLICENSED"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I just wanted to have the BSCSCAN's verification.
Since solidity 0.6.8 you should set a License header to your contract, so you need to add this at the first line of your file:
// SPDX-License-Identifier: UNLICENSED
You can use the UNLICENSED or use one of the predefined licenses. Here is the list: https://spdx.org/licenses/
More information about the SPDX License herader here: https://forum.openzeppelin.com/t/solidity-0-6-8-introduces-spdx-license-identifiers/2859
This should fix your first Warning and the last error.
After making this change I was able to compile the contract using remix, but I think that all other errors are related with the compiler version, could you share version and other settings that you see in the compiler options?
I'm using Compiler 0.8.4+commit.c7e474f2
Also you need to remove the public keyword in the constructor, it is ignored by the compiler. The final result is:
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";
contract HelpingArtistsAtRisk is ERC20 {
constructor(uint256 initialsupply) ERC20 ("Helping Artists At Risk", "HAAR"){
_mint(msg.sender,initialsupply);}
}

How to update deployed Ethereum smart contract with ABI only through console (Truffle)

I need to update value on deployed contract ( I dont have sol neither it has been deployed on my platform )
I want to update param with setter in contract and call getter to see changed value .. always default value comes back!
here is the code Im using :
new web3.eth.Contract(HelloWorld.abi,'0x085Ab4C596535FFCE5B520D277f1C01236a656CB').methods.setMessage('Hi').call()
=> Result {}
then call :
new web3.eth.Contract(HelloWorld.abi,'0x085Ab4C596535FFCE5B520D277f1C01236a656CB').methods.getMessage().call()
=>
'hello world10' 🤔
Im using Truffle console:
truffle console --network ropsten
one comment if I use :
HelloWorld.deployed().then(instance => instance.setMessage('new Hi').call())
then call:
HelloWorld.deployed().then(instance => instance.getMessage.call()).then(result => message = result)
then I got expected value .. but I don't have deployed contract. neither sol. all what I have part ABI
Is it wrong with my calls that should be async .. or I need to redeploy contract ?
Im still new in this crypto-world 🙂
welcome to the "crypto-world" as you named it.
I've got a bit lost on your question but what you want is to deploy a contract with an initial message and then change that message using setMessage method, all through the console.
First thing you are doing wrong is calling the "setMessage" method using .call(). When you want to change something in the blockchain, you will send a transaction, and to send a transaction you need to specify an account. The correct method should be .send({ from: "you-account-address" }).
In order to simplify a bit, let me just show a few lines that you can use and then explain
$ > truffle console --network ropsten
$ (truffle) > helloInstance = await HelloWorld.deployed()
$ (truffle) > await helloInstance.getMessage()
$ (truffle) > await helloInstance.setMessage("new Hi", { from: "you-account-address" })
So, basically, all calls are async. First, you call HelloWorld.deployed() because when you deployed the contracts with truffle, truffle created a folder named "build" where it saved the contracts with all the necessary data, that's why you don't need to specify the address neither the abi. This is totally different from using web3.js in which you need to specify both.
Then, you can just call the methods.
You can find more detailed information here https://www.trufflesuite.com/docs/truffle/getting-started/interacting-with-your-contracts

Can I reference a DataContract and its proxy version from same class

I'm dipping my foot into WCF and am trying to make a simple test project that can both consume the service as a service and also directly instantiate it's classes and work with them.
I had an earlier working version where data passed was just primitive types. However, when I attempted to convert to using data contracts, I'm getting conflicts in whether it's referencing the proxy-declared version of the contract or the version from the project itself.
Question: Is it possible to do this and if so, how would I resolve the data contract references?
private void Test()
{
MyService fssDirect = new MyService(); // direct instantiation
MyServiceClient fssService = new MyServiceClient(); // Service proxy
ClientCredentialsContract Client = new ClientCredentialsContract();
ResponseDataContract Result = new ResponseDataContract();
if (CallAsService)
{
Result = fssService.Create(Client, Request);
}
else
{
Result = fssDirect.Create(Client, Request);
}
}
In the above, any reference to the RequestDataContract and ClientCredentialsContract types indicates
Warning: The type 'MyContracts.RequestDataContract' in 'C:...\Test\MyServiceProxy.cs' conflicts with the imported type 'MyContracts.RequestDataContract' in 'C:...\MyService\bin\Debug\Contracts.dll'. Using the type defined in 'C:...\Test\MyServiceProxy.cs'.
(Names changed and paths shortened to protect the innocent)
Thanks,
John
When you create the proxy for your service, try referencing the assembly which contains the data contracts (if using "Add Service Reference", go to the advanced options, select "reuse types in referenced assemblies"; if using svcutil, use the /r argument). This way the tool won't generate the data contracts and you won't have the conflicts.