1

I am new to Solidity programming and writing smart contracts for one of the application. Here are my two contracts. I am using truffle and testrpc as tool. I am getting error consistently. Need guidance. I have seen earlier threads with similar subject lines but they dont help. I already tried changing the name of the function as well.

//Certificate.sol

contract Certificate {
    address private addressSelf;
    bytes32 private certName;

    function Certificate(bytes32 _certName) {
        addressSelf = msg.sender;  
        certName = _certName;
    }  
}

//Participant.sol

contract Participant {
    address private addressSelf;
    bytes32 private participantName;

    struct CertStruct {
        Certificate certificateData;
        bool isCertificate;
    }

    mapping (address => CertStruct) public certStructs;
    mapping (uint => address) public certIndex;
    uint public noOfCerts;

    function Participant(bytes32 _partName) {
        addressSelf = msg.sender;  // just set the self
        participantName = _partName;
        noOfCerts = 0;
    }

    function isCertGranted(address certAddress) public constant returns(bool) {
        return certStructs[certAddress].isCertificate;
    }

    function grantCertToParticipant(address certAddress, Certificate certificate) payable public returns (bool)
    {
        if(!isCertGranted(certAddress)) return false;

        CertStruct memory newCertStruct;
        newCertStruct.certificateData = certificate;
        newCertStruct.isCertificate = true;
        certStructs[certAddress] = newCertStruct;
        certIndex[noOfCerts] = certAddress;
        noOfCerts++;

        return true;
    }
}

//participant.js

var CertificateSol = artifacts.require("./Certificate.sol");

var ParticipantSol = artifacts.require("./Participant.sol");

contract('Participant', function() {

    it("should put certificate in the one participant", function() {

        var newCert;
        var newPart;

        return CertificateSol.new('CertName').then(function(newCertInstance) {
            newCert = newCertInstance;
        }

        return ParticipantSol.new('Name of Participant').then(function(newPartInstance) {
            newPart = newPartInstance;

        newPart.grantCertToParticipant.sendTransaction(newCert.address, newCert, { from : web3.eth.accounts[0], gas: 3000000 }).then(function(returnFlag){

            newPart.noOfCerts.call().then(function(certNumber){
              console.log('certNumber is ' + certNumber.toString(10));
          });
        }).catch(function(err){
          console.log('I am at grantCertToParticipant err ' + err);
        });

    });    
}
1

First, you don't need to explicitly send transaction, it's enough to call a method:

newPart.grantCertToParticipant(newCert.address, newCert, { from : web3.eth.accounts[0], gas: 3000000 })

Second, newCert it's a contract proxy object, so don't pass it to web3 call. It's enough just to send newCert.address. I will leave only address in method signature:

function grantCertToParticipant(address certAddress) payable public returns (bool)

this line unfortunately doesn't make much sense:

newCertStruct.certificateData = certificate; 

as you cannot store the whole contract but only reference in the form of an address so it's redundant.

  • Thanks, Jakub. grantCertToParticipant is the state changing function so I suppose I should use sendtransaction. I have 5-6 levels of domain objects hierarchy which I want to maintain maps against address. Not sure if I can access the contract instance of e.g. Certificate just by using address. Is there any suggestive way? Also, the main question – what is wrong in the signature of the function “function grantCertToParticipant(address certAddress, Certificate certificate) payable public returns (bool)”, it is throwing BigNumber exception? Thanks in advance. – golra03 Jul 14 '17 at 8:59
  • 1) You don't need to manually sendTransaction web3 will do it automatically if you method in not annotated with constant. 2) Address and interface are enough to access contract on-chain. 3) Don't pass the contract proxy newCert it will keep throwing an error. – Jakub Wojciechowski Jul 14 '17 at 10:06
  • Great!!! That solved the problem and built one critical concept for me. I removed newCert and problem got solved. I could do Certificate.at(0xXXX) to get the newCert instance and work further. Great help!! Thanks!! – golra03 Jul 15 '17 at 15:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.