artifact.require() statement in inheritance? - migration

Hi guys my question i very simple.
I have this contract:
B.sol
...
contract A {
...
}
contract B is A {
...
}
When i migrate to blockchain my B.sol i need to deploy every single contracts inside?
Choose one of the answers and explain why please.
var B = artifacts.require("B");
module.exports = function(deployer) {
deployer.deploy(B);
};
var A= artifacts.require("A");
var B= artifacts.require("B");
module.exports = function(deployer) {
deployer.deploy(A);
deployer.deploy(B);
};

The answer you're looking for is most likely #1. When contracts inherit from other contracts, only a single contract is created during deployment. Conceptually, it's the same as other object-oriented languages. From the Solidity docs:
When a contract inherits from multiple contracts, only a single
contract is created on the blockchain, and the code from all the base
contracts is copied into the created contract.
Technically, you can have a child contract that references a deployed parent contract (see below). But, I can't think of a situation where this would be a good design.
pragma solidity ^0.4.18;
contract A {
uint256 public balance;
function() public payable {
balance = msg.value;
}
}
contract B is A {
uint256 i;
A a;
function B(address _a) public {
a = A(_a);
}
function receiveForParent() public payable {
a.transfer(msg.value);
}
function getParentBalance() public constant returns (uint256) {
return a.balance();
}
}
Here, you can deploy A then pass that address in when deploying B. In this case, calling B.balance() or using the fallback function is valid since you're inheriting the logic. However, B.balance() != A.balance(). (Note that B.getParentBalance() == A.balance()).

Related

How to access function of a contract instantiated with new?

I'm instantiating the contract called "Elector", applying new inside the function below, so far it works and the result is this one:
The contract is instantiated in memory with this address.
So, how do I access the getInformation() function inside this contract to use both in this main contract and in ethers in the dApp?
MAIN CONTRACT:
function updateConfirmedVotes(uint candidateId, VoteType electorVoteType) public {
_updateTotalElectoresVoted();
_pollingByCandidate[candidateId].votes.total += 1;
_pollingByCandidate[candidateId].votes.totalPercentage = _calculePercentageOfVote(_pollingByCandidate[candidateId].votes.total);
_pollingByCandidate[candidateId].electors.push(new _Elector({wallet: msg.sender, vote: electorVoteType}));
}
ELECTOR CONTRACT:
contract _Elector {
address private _wallet;
VoteType private _vote = VoteType.DID_NOT_VOTED;
constructor(address wallet, VoteType vote) {
_wallet = wallet;
_vote = vote;
}
function getInformation() external view returns (address, VoteType) {
return (_wallet, _vote);
}
}
Define a contract type variable within your Main contract, passing it pointer to the newly deployed Elector contract. Then you can invoke external/public functions defined by the contract type on the external address.
pragma solidity ^0.8;
contract Elector {
// ...
}
contract Main {
Elector elector;
function deployElector() external {
// returns pointer to the newly deployed contract
elector = new Elector();
}
function getInformationFromElector() external view returns (address, Elector.VoteType) {
// calls the external contract
return elector.getInformation();
}
}

How to run multiples contracts functionalities in a single contract Solidity

I'm new to Solidity but I can't find much information about my problem.
For example, I want to make different contracts for different functionalities (I see them as classes)
For example
Main contract
// SPDX-License-Identifier: None
pragma solidity >=0.8.6;
import "./AuthContract.sol";
contract Contract {
string public message;
constructor() {
message = "test";
}
function getMessage() public view returns(string memory) {
return message;
}
}
and second contract
contract Auth {
struct UserDetail {
address addr;
string name;
string password;
string CNIC;
bool isUserLoggedIn;
}
mapping(address => UserDetail) user;
// user registration function
function register(
address _address,
string memory _name,
string memory _password,
string memory _cnic
) public returns (bool) {
require(user[_address].addr != msg.sender);
user[_address].addr = _address;
user[_address].name = _name;
user[_address].password = _password;
user[_address].CNIC = _cnic;
user[_address].isUserLoggedIn = false;
return true;
}
// user login function
function login(address _address, string memory _password)
public
returns (bool)
{
if (
keccak256(abi.encodePacked(user[_address].password)) ==
keccak256(abi.encodePacked(_password))
) {
user[_address].isUserLoggedIn = true;
return user[_address].isUserLoggedIn;
} else {
return false;
}
}
// check the user logged In or not
function checkIsUserLogged(address _address) public view returns (bool) {
return (user[_address].isUserLoggedIn);
}
// logout the user
function logout(address _address) public {
user[_address].isUserLoggedIn = false;
}
}
How could I use the functionalities from that contract in the main contract?
Is such a thing possible in the blockchain?
I am quite new here also but i can solve your problem, if not solve i can lead you to a good path .
so firstly you said you want to create multiple contract for different functionalities, this is good but keep in my you are going to exhaust a lot of gas.
so the answer to your problem is easy you can just read it and implement it.
if you want to use a contract in the Another contract (main in your case) you can do it in two ways(according to my knowledge there might be other).
using new keyword
using address of your previously deployed contract
we will be using the First case as i suppose you havenot deployed the second contract yet
In Order to do it you can use
Auth myObj=new Auth();
This will create a new instance of the contract Auth in your main contract and now you can use the Auth contract's function in your Main contract.you can create a function copy the above line and you can use the Functions using dot operator.
myObj.register(_address,_name,moreandmore);
I believe this will solve your problem if not you can ask it.
Thank You!

When I make a contract that inherits a contract, do I need to insert using phrase one more time?

contract A {
using SafeMath for uint256
}
contract B is A {
//using SafeMath for uint256
function mul () public {
uint256 test = 1;
test.mul(3);
}
}
Without contract B's using phrase i encountered "Member "mul" not found or not visible after argument-dependent lookup in contract uint256."
When i make contract that inherit other contract which has "using SafeMath for uint256", do i have to insert using phrase one more time?
It depends on the compiler version.
Since 0.7, you need to reimport the library in each contract separately.
From the docs:
The using A for B; directive is active only within the current scope (either the contract or the current module/source unit), including within all of its functions, and has no effect outside of the contract or module in which it is used.
pragma solidity ^0.8;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.2/contracts/math/SafeMath.sol";
contract A {
using SafeMath for uint256;
}
contract B is A {
using SafeMath for uint256; // reimported the library
function foo() pure public returns (uint256) {
uint256 test = 1;
return test.mul(3);
}
}
However, in 0.6 and older versions, the imported library is available in the child contracts as well.
pragma solidity ^0.6;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.2/contracts/math/SafeMath.sol";
contract A {
using SafeMath for uint256;
}
contract B is A {
// no need to reimport the library
function foo() pure public returns (uint256) {
uint256 test = 1;
return test.mul(3);
}
}

Truffle test in solidity with sending value

duplicating my question from SA:
I have a simple contract with public function, that can receive value and do something based on that value:
pragma solidity >= 0.8.0 < 0.9.0;
contract ContractA {
uint public boughtItems = 0;
uint price = 10;
address [] buyers;
function buySomething() public payable {
require(msg.value >= price, "Sent value is lower");
boughtItems++;
buyers.push(msg.sender);
}
}
and in test folder of my Truffle project I have test contract:
pragma solidity >=0.8.0 <0.9.0;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/TicketsRoutes.sol";
contract TestTicketsRoutes {
ContractA instance;
address account1 = 0xD8Ce37FA3A1A61623705dac5dCb708Bb5eb9a125;
function beforeAll() public {
instance = new ContractA();
}
function testBuying() public {
//Here I need to invoke buySomething with specific value from specific address
instance.buySomething();
Assert.equal(instance.boughtItems, 1, "Routes amount is not equal");
}
}
How do I invoke function of ContractA in my TestContractA with passing value and sender?
You can use the low-level call() Solidity function to pass a value.
(bool success, bytes memory returnedData) = address(instance).call{value: 1 ether}(
abi.encode(instance.buySomething.selector)
);
But, in order to execute the buySomething() function from a different sender, you need to send it from a different address than the TestTicketsRoutes deployed address.
So you'll need to change your approach and perform the test from an off-chain script (instead of the on-chain test contract) that allows you to sign the transaction from a different sender. Since you tagged the question truffle, here's an example of executing a contract function using the Truffle JS suite (docs).
const instance = await MyContract.at(contractAddress);
const tx = await instance.buySomething({
from: senderAddress,
value: web3.toWei(1, "ether")
});

Solidity: Are these sentences the same? Or do they mean different things?

In order to calling a function 'isContract', with the parameter 'to' being an address, are valid both ways? :
to.isContract()
isContract(to)
Does Solidity allow both ways?
I have found both in different codes, and I don't know if just 'isContract(to)' is the right one, or if 'to.isContract()' means another different thing.
Thanks a lot for your help.
They're not the same.
to.isContract() suggests that you have defined an interface (in your code) that defines a isContract() function, and that the contract deployed at the to address implements this interface.
pragma solidity ^0.8.0;
interface ExternalContract {
function isContract() external returns (bool);
}
contract MyContract {
function foo() external {
ExternalContract to = ExternalContract(address(0x123));
bool returnedValue = to.isContract(); // calling `to`'s function `isContract()`
}
}
isContract(to) calls an external or internal function in your contract.
pragma solidity ^0.8.0;
contract MyContract {
function foo() external {
address to = address(0x123);
bool returnedValue = isContract(to); // calling your function `isContract()`
}
function isContract(address to) internal returns (bool) {
return true;
}
}
Edit: I forgot about one more case - using a library containing the isContract() function for an address. Example OpenZeppelin implementation: definition, usage.
library AddressLibrary {
function isContract (address _address) {
return true;
}
}
contract MyContract {
using AddressLibrary for address;
function foo() external {
address to = address(0x123);
bool returnedValue to.isContract(); // calling your function `isContract(to)`
}