Read variably-sized data from another smart contract - solidity

I have two contracts as shown below. I am saving document details to document contract through the DocInfo contract. But when I tried to get the details through the docINfo contract I am getting empty result. Is there anything I missed here?
pragma solidity 0.5.0;
contract DocumentContract {
struct Document{
string DocumentNo;
address DigitalID;
}
mapping(string=>Document) doc;
function CreateDocument(string calldata DocumentNo,address DigitalID) external {
doc[DocumentNo] = Document({
DocumentNo: DocumentNo,
DigitalID: DigitalID
});
}
function GetDocument(string calldata documentNumber) external view returns(address) {
Document memory document = doc[documentNumber];
return (document.DigitalID);
}
}
contract DocInfo {
function CreateDocument(address digitalID,string memory documentId) public returns (bool success) {
address contractAddress =<<Document contract address>>;
DocumentContract doc = DocumentContract(contractAddress);
doc.CreateDocument(documentId,digitalID);
return true;
}
function GetDocument(string memory documentId)
public view returns (address) {
address contractAddress = <<Document contract address>>;
DocumentContract doc = DocumentContract(contractAddress);
address digitalId = doc.GetDocument(documentId);
return digitalId;
}
}

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

I'm trying to test out a smart contract using Remix but "This contract may be abstract "is appeared

I'm trying to test out a smart contract using Remix.
They compile fine, but when I deploy thz contractenter code here I get this error:
This contract may be abstract, not implement an abstract parent's methods completely or not invoke an inherited contract's constructor correctly.
Anyone know what could be going on? Thanks!
pragma solidity ^0.8.7;
interface UDL_SC_lifecycle_manager {
struct TP {
uint id;
}
struct OP {
uint id;
}
struct BP{
uint id;
}
//ContractDescriptionMetaData
struct CDMD {
uint ID;
address providerAdress;
TP TechnicalPerspective;
OP OperationalPerspective;
BP BusnissPerspective;
}
function PublishDesc(CDMD memory ContractDescription, address provider) external ;
function UpdateDesc(CDMD memory ContractDescription, address provider) external ;
function DestroyDesc(address contractadr, uint contractID) external returns(bool);
}
abstract contract SmartRegistryService is UDL_SC_lifecycle_manager{
mapping(address => CDMD) CDMDS;
address contractAdresse;
address proprietaire;
event DescriptionPublished(string _msg);
event DescriptionUpdated (string _msg);
event NotExist (string _msg);
event Deleted (string _msg);
function publishdesc (CDMD memory NVContractDescriptionMetaData, address providerAdress) public {
CDMDS[providerAdress] = NVContractDescriptionMetaData;
emit DescriptionPublished(" smart contract published successfully!");
}
modifier ProviderOnly(address provider){
require(msg.sender == provider);
_;
}
function updatedesc (CDMD memory NVContractDescriptionMetaData, address providerAddress, uint contractID) public {
bool statue = false;
CDMD storage newContractDescriptionMetaData = CDMDS[providerAddress];
if((newContractDescriptionMetaData.ID== contractID)&&(newContractDescriptionMetaData.providerAdress == providerAddress)){
statue = true;
CDMDS[providerAddress] = NVContractDescriptionMetaData;
emit DescriptionUpdated("smart contract updated successfully!");
}else{
emit NotExist("smart contract notExist!");
}
}
function destroydesc(address providerAddress, uint contractID) public {
CDMD storage newContractDescriptionMetaData = CDMDS[providerAddress];
if (newContractDescriptionMetaData.ID == contractID) {
delete CDMDS[providerAddress];
emit Deleted("smart contract deleted successfully!");
}
}
}

What is the type of `this` object in solidity

In the following claimPayment function that is used to claim a payment made earlier to this contract, the line bytes32 message = prefixed(keccak256(abi.encodePacked(msg.sender, amount, nonce, this))); has this as part of the signed message. This makes me wonder what is this and what the type of this is. If I'm returning this in a function, what type is used for it? Thanks.
function claimPayment(uint256 amount, uint256 nonce, bytes memory signature) public {
require(!usedNonces[nonce]);
usedNonces[nonce] = true;
// this recreates the message that was signed on the client
bytes32 message = prefixed(keccak256(abi.encodePacked(msg.sender, amount, nonce, this)));
require(recoverSigner(message, signature) == owner);
payable(msg.sender).transfer(amount);
}
this is a pointer to the current class instance, as in many other programming languages. You can for example point to public methods:
pragma solidity ^0.8.0;
contract MyContract {
function foo() external {
this.bar();
}
function bar() public {
}
}
When this is typecasted, it takes a form of the address, where the current instance is deployed.
pragma solidity ^0.8.0;
contract MyContract {
function foo() external view returns (bytes memory) {
return abi.encodePacked(this);
}
function bar() external view returns (address) {
return address(this);
}
}

How to pass struct from contract A to contract B? Best practice

I found such way, when one general interface with structure is created and then contract A and B inherit the interface with structure.
But I'm wondering if there are other ways?
And could there be a case where a contract with a structure can be updated?
pragma experimental ABIEncoderV2;
pragma solidity ^0.6.0;
interface params {
struct structTest {
uint256 data;
}
}
contract contractA is params{
function testCall(structTest calldata _structParams) public pure returns (uint256){
return _structParams.data;
}
}
contract contractB is params{
contractA aContractInstance;
constructor (address _a) public {
aContractInstance = contractA(_a);
}
function test(structTest calldata _structParams) public view returns(uint256){
// call contract A from B and pass structure
return aContractInstance.testCall(_structParams);
}
}
interface IContractA {
struct User {
address addr;
}
function getUser(aaddress addr) external view returns (User memory user);
}
contract contractB{
function getUserFromContractA(address addr) public view
returns (IContractA.User memory user)
{
ContractA = IContractA(addrContractA);
user = ContractA.getUser(addr);
}
}

Compiling a smart contract without removing line breaks

I'm new to write a smart contract with Ethereum.
According to an official document, compiling a smart contract needs to remove all the line-breaks in the contract's source-code :
var greeterSource = 'contract mortal { address owner; function mortal() { owner = msg.sender; } function kill() { if (msg.sender == owner) suicide(owner); } } contract greeter is mortal { string greeting; function greeter(string _greeting) public { greeting = _greeting; } function greet() constant returns (string) { return greeting; } }'
var greeterCompiled = web3.eth.compile.solidity(greeterSource)
https://ethereum.gitbooks.io/frontier-guide/content/contract_greeter.html
As I think the removing process is not smart, I want to compile the code itself like:
var greeterCompiled = web3.eth.compile.solidity_infile( "greeter.txt" )
# The function "solidity_infile" does not exists actually,
# but represents what I want to do.
greeter.txt
contract
mortal {
/* Define variable owner of the type address*/
address owner;
/* this function is executed at initialization and sets the owner of the contract */
function mortal() { owner = msg.sender; }
/* Function to recover the funds on the contract */
function kill() { if (msg.sender == owner) suicide(owner); }
}
contract greeter is mortal {
/* define variable greeting of the type string */
string greeting;
/* this runs when the contract is executed */
function greeter(string _greeting) public {
greeting = _greeting;
}
/* main function */
function greet() constant returns (string) {
return greeting;
}
}
Does anyone how to do that?
The compiler I'm using is Solidity.
How about loading the contract from a file into var someContractText and then do the following
someContractText = someContractText.replace(/(\r\n|\n|\r)/gm,"");