Ethereum Pet Shop tutorial - ParserError: Expected pragma, import directive or contract/interface/library definition - solidity

I'm trying to follow the tutorial here to learn how to code a dapp. I put together this .sol code (well, copy/pasted...):
pragma solidity ^0.5.0;
contract Adoption {
address[16] public adopters;
}
// Adopting a pet
function adopt(uint petId) public returns (uint) {
require(petId >= 0 && petId <= 15);
adopters[petId] = msg.sender;
return petId;
}
// Retrieving the adopters
function getAdopters() public view returns (address[16] memory) {
return adopters;
}
and there's another file that was already there. When I run the truffle compile command I see the following:
ParserError: Expected pragma, import directive or contract/interface/library definition.
function adopt(uint petId) public returns (uint) {
^------^
Compilation failed. See above.
Truffle v5.1.34 (core: 5.1.34)
Node v12.18.2
Any idea what I might be missing?

Functions must be within the contract scope:
pragma solidity ^0.5.0;
contract Adoption {
address[16] public adopters;
// Adopting a pet
function adopt(uint petId) public returns (uint) {
require(petId >= 0 && petId <= 15);
adopters[petId] = msg.sender;
return petId;
}
// Retrieving the adopters
function getAdopters() public view returns (address[16] memory) {
return adopters;
}
} // <= closing brace

Related

Solidity, is there gas-wise difference between transfer and call with 2300?

I am trying the below code, elementary reentrancy example.
The current code works but transfer or send doesn't work. It reverts. What are the reasons?
Note: I chose setCaller to reenter to test the fact that updating the dirty state variable (already modified var in the same tx) takes less gas.
// SPDX-License-Identifier: Unlicensed
pragma solidity 0.8.7;
contract TestFund {
// success, if caller is itself.
address public caller;
constructor() payable {}
function getBalance() public view returns (uint) {
return address(this).balance;
}
function emptyFn(address dummy) public {}
function setCaller(address _caller) public {
caller = _caller;
}
function withdraw() external {
caller = msg.sender;
// require(payable(msg.sender).send(1 wei));
// payable(msg.sender).transfer(1 wei);
(bool success, bytes memory data) = payable(msg.sender).call{gas: 2300, value:1 wei}("");
require(success);
}
}
contract Attack {
function getBalance() public view returns (uint) {
return address(this).balance;
}
function attack(address target) external {
TestFund(target).withdraw();
}
receive() external payable {
if (getBalance() == 1 wei) {
TestFund(msg.sender).setCaller(msg.sender);
}
}
}

How to update the version of the solc compiler?

I have a smart contract and I want to get its abi and bin via the command:
solc --optimize --abi ./firstContract.sol -o build
, then then I get the following error:
WARNING: cgroup v2 is not fully supported yet, proceeding with partial
confinement ./firstContract.sol:1:1: Error: Source file requires
different compiler version (current compiler is
0.5.16+commit.9c3226ce.Linux.g++ - note that nightly builds are considered to be strictly less than the released version pragma
solidity ^0.8.0;
here is my contract code:
pragma solidity ^0.8.0;
contract BalanceCheck {
uint256 balance;
address public admin;
constructor() {
admin = msg.sender;
balance = 0;
updateBalance();
}
function constr() public {
admin = msg.sender;
balance = 0;
updateBalance();
}
function updateBalance() internal {
balance += msg.value;
}
function Withdrawl(uint256 _amt) public {
require(msg.sender == admin);
balance = balance - _amt;
}
function Deposite(uint256 amt) public returns (uint256) {
return balance = balance + amt;
}
function Balance() public view returns (uint256) {
return balance;
}
}

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)`
}

Assert.equal is not available when running Truffle Tests

I have a simple contract and I am trying to write Solidity tests for that contract in Truffle. Below are the code samples -
File: dummycontract.sol
pragma solidity ^0.4.17;
contract DummyContract {
uint[] public elements;
function addElement(uint element) public {
elements.push(element);
}
function getNumberOfElements() public view returns(uint) {
uint numElements = uint(elements.length);
return numElements;
}
}
And the test file -
pragma solidity ^0.4.17;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/dummycontract.sol";
contract TestZombieFactory {
function testInitialState() public {
DummyContract dummyContract = DummyContract(DeployedAddresses.DummyContract());
uint numberOfElements = dummyContract.getNumberOfElements();
Assert.equal(numberOfElements == 0);
}
}
On running truffle test, I get the following error -
TypeError: Member "equal" is not available in type(library Assert) outside of storage.
Assert.equal(numberOfElements == 0);
Can someone please explain this to me?
Your usage of Assert.equal() is not correct. It expects two values and does the comparison within the function. The function signature is
function equal(uint A, uint B, string message) constant returns (bool result)
Change your test contract to the following and it will work.
pragma solidity ^0.4.17;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/dummycontract.sol";
contract TestZombieFactory {
function testInitialState() public {
DummyContract dummyContract = DummyContract(DeployedAddresses.DummyContract());
uint numberOfElements = dummyContract.getNumberOfElements();
Assert.equal(numberOfElements, 0, "Number of elements should be 0");
}
}
You should replace
Assert.equal(numberOfElements == 0);
with
Assert.equal(numberOfElements,0);

Can someone please give working example of interface in solidity?

I am getting error "This contract does not implement all functions and thus cannot be created." while using interface in solidity can someone help me on this or please give me working example of interface in solidity?
pragma solidity ^0.4.0;
interface Audit {
function CheckBlance() public returns(bool);
function lending() public returns(bool);
}
contract Fin_Inst is Audit{
uint public Money;
function Fin_Inst(uint Value) public {
Money = Value;
}
function Deposit(uint DepAmount) public{
Money = Money + DepAmount;
}
function Withdraw(uint WithdAmount) public{
if(CheckBlance(WithdAmount) == true){
Money = Money - WithdAmount;
}
}
function Balance() public constant returns (uint){
return Money;
}
function CheckBlance(uint WithdAmount) public returns (bool){
return Money >= WithdAmount;
}
function lending() public returns (bool){
return Money > 0;
}
}
I've made small changes and now when you run Create Fin_Inst it executes without any error messages.
Seems like an error was in function parameter in interface method CheckBalance(uint WithdAmount).
Here is the edited code:
pragma solidity ^0.4.19;
interface Audit {
function CheckBalance(uint WithdAmount) public view returns(bool);
function lending() public view returns(bool);
}
contract Fin_Inst is Audit{
uint public Money;
function Fin_Inst(uint Value) public {
Money = Value;
}
function Deposit(uint DepAmount) public {
Money = Money + DepAmount;
}
function Withdraw(uint WithdAmount) public {
if(CheckBalance(WithdAmount) == true){
Money = Money - WithdAmount;
}
}
function Balance() external view returns (uint) {
return Money;
}
function CheckBalance(uint WithdAmount) public view returns (bool) {
return Money >= WithdAmount;
}
function lending() public view returns (bool) {
return Money > 0;
}
}
Yes, in order to implement a method you must respect the signature (same name and params) completly.
For example, you can have in your Contract 3 different methods like
method1(), method1(unit x) and method1(unit[] xs)
To implement this interface, you must code the 3 methods in the child Contract. So, if you only implement method1() they are still pending method1(unit x) and method1(unit[] xs).
This is called Function overloading. Therefore CheckBalance(uint WithdAmount) is not the same as CheckBalance()