4

I'm just getting started with solidity, and I'm working on a contract that calculates the periodic payment on an amortized loan. My goal is to implement the annuity formula:

annuity formula

I've started a library for rational data and a struct for the fraction. In order for the library function to compile the function signature requires any struct parameters be marked with the storage keyword.

library Rational
{
    struct FractionUint
    {
        uint numerator;
        uint denominator;
    }

    function multiply(FractionUint storage self, FractionUint storage other)
    {
        self.numerator *= other.numerator;
        self.denominator *= other.denominator;
    }

...
}

contract testRational
{
    using Rational for Rational.FractionUint;
    Rational.FractionUint f1;
    Rational.FractionUint f2;

    function testMultiply()
    {
        f1 = Rational.FractionUint(1,10);
        f2 = FractionUint(100,2);
        f1.multiply(f2);
        if (f1.numerator != 100)
            throw;
        if (f1.denominator != 20)
            throw;
    }

    /*
    function testMultiply2()
    {
        var f3 = Rational.FractionUint(1,10);
        var f4 = Rational.FractionUint(100,2);
        f3.multiply(f4);
        if (f3.numerator != 100)
        throw;
        if (f3.denominator != 20)
        throw;
    }
    */
}

Compiling testMultiply2 restults in the error:

Error: Member "multiply" is not available in struct FractionUint memory outside of storage.

There are multiple intermediate steps for which I'd like to use some variables defined in the scope of the contract function.

Can a library function called from a contract function perform operations on variables defined in the contract function scope?

5

Libraries can operate on structs in storage (that's one of their main purposes) but are currently unable to operate on memory structs (lifting this limitation is planned, though).

For your general problem concerning fractional numbers, I would propose different solutions, though:

  1. either combine the two uints into a single uint (256 bits is a lot) or use uint[2] instead of the struct
  2. wait for Solidity to receive fixed point integers (they should come "soon")
  • Excellent, I look forward to the fixed point types. I'll hold off until then. – Robert Graves Mar 8 '16 at 22:49

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.