To learn a bit about ethereum, I thought I'd code up a simple loan contract. I added a few simple properties for any loan, and I immediately ran into problems.
contract Loan
{
address lender;
address borrower;
uint amount;
???? interestRate;
...
}
What type do I use for the interest rate? Looking at the solidity types documentation, the primitive types include Boolean and multiple kinds of integers. There is no primitive for decimal numbers.
Without decimal numbers, how do I calculate the interest?
You can use another unit.
Like multiply every percentage by 100, you achieve a 2 number after comma precision
1% => 100
0,1% => 10
0,01% => 1
If it's not enough, you can use other multipliers.
The Solidity changelog shows that fixed point types will be included in version 0.3.0 which is in development.
Related
I am trying to do the following calculation with solidity:
3,000 / 45,000,000 = 0.000067 with the following method:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
function divide(uint _num1, uint _num2) public pure returns(uint _result) {
return (_num1 /_num2 );
}
But obviously, I am getting the results as zero.
I am aware that solidity for transactions uses 18 decimal points (using Wei), however, I could not find in the replay to all the previous questions regarding the decimals in solidity how to do it for regular numbers, or regular calculations. Also most of the time it does not even work with transactions.
What is the actual commonly used standard practice method to do "ANY" division from "ANY" number, regardless being for Ether, Tokens, or regular calculations?
I mean a method that would work for 3 / 100 just as well as 2.5 / 3.7?
Floating-point arithmetics are not supported in Solidity however you can use fixed-point arithmetics considering that you have 18 points of decimals if you use uint256.
I already know how to calculate x^n, where x is a floating point number and n is an integer. However, I want to implement a price curve, using the formula:
y = 0.5 * (x^1.5)
To do this, I need to be able to do exponentiation where the power is a floating-point (or fixed-point) value. How can I do this in Solidity?
Solidity does not offer built-in math functions, therefore you must use a library.
Paul Berg's PRB-math library provides fixed-point mathematics operations for Solidity.
I am wondering besides these below mathematical expressions are there any other functions available to call inside a smart contract? Like math functions, like pi, sin, cosine, random() etc?
I am wondering if one can write smart contracts that require a little more than just basic arithmetic.
Below Image is taken from this page:
https://docs.soliditylang.org/en/develop/cheatsheet.html#function-visibility-specifiers
Solidity doesn't natively support storing floating point numbers both in storage and memory, probably because the EVM (Ethereum Virtual Machine; underlying layer) doesn't support it.
It allows working with them to some extent such as uint two = 3 / 1.5;.
So most floating point operations are usually done by defining a uint256 (256bit unsigned integer) number and another number defining the decimal length.
For example token contracts generally use 18 decimal places:
uint8 decimals = 18;
uint256 one = 1000000000000000000;
uint256 half = 500000000000000000;
There are some third-party libraries for calculating trigonometric functions (link), working with date time (link) and other use cases, but the native language currently doesn't support many of these features.
As for generating random numbers: No native function, but you can calculate a modulo of some pseudo-random variables such as block.hash and block.timestamp. Mind that these values can be (to some extent) manipulated by a miner publishing the currently mined block.
It's not recommended to use them in apps that work with money (pretty much most of smart contracts), because if the incentive is big enough, there can be a dishonest miner who can use the advantage of knowing the values before rest of the network and being able to modify them to some extent to their own benefit.
Example:
// a dishonest miner can publish a block with such params,
// that will result in the condition being true
// and their own tx to be the first one in the block that executes this function
function win10ETH() external {
if (uint256(blockhash(block.number)) % 12345 == 0) {
payable(msg.sender).transfer(10 ether);
}
}
If you need a random number that is not determinable by a miner, you can use the oracle approach, where an external app (called oracle) listens to transactions in a predefined format (generally also from&to specific addresses), performs an off-chain action (such as generating a random number, retrieving a google search result, or basically anything) and afterwards sends another transaction to your contract, containing the result of the off-chain action.
I am new in solidity language. Have seen their documentation. Is there any floating point data type ?
There is no floating point in Solidity. You should keep numbers in whole number format.
You can place decimal place in your front-end code. Take a look at how ERC20 contract was designed.
Good read: https://medium.com/#jgm.orinoco/understanding-erc-20-token-contracts-a809a7310aa5
There is no native support for floating-point numbers in the core language, but they are available via libraries, such as ABDKMathQuad.
You could try Paul Razvan Berg's PRBMath
You can have floating point constants in Solidity, but only with a unit designation gwei (which multiplies by 10^9, or ether (which multiplies by 10^18). For example, if you write 0.1 ether in your Solidity code, it is turned into 100000000000000000 (= 10^17 wei). However, after multiplication by the fixed point multiplier in the unit suffix, there can't be any fractional decimals left. For example you can't specify 1.00000000000000000000000001 ether, because that would leave you with a fractional number of wei.
More generally, what you are probably asking about is how to do fixed point mathematical calculations in Solidity, since floating point is not supported. There are many tutorials online explaining how to calculate fractional values using fixed point (just search for "fixed point arithmetic tutorial", for a wide range of languages (the principles apply directly to Solidity too). You can generally implement fixed point with very little code (addition and subtraction work without any special care, as long as both operands have already been multiplied by the same fixed point multiplier, whereas for multiplying two fixed point numbers, you just divide by the fixed point multiplier after multiplying two fixed point numbers that have already each been multiplied by the same fixed point multiplier). Or you can use one of the math libraries linked in other answers.
This might be a simple solution but its a headache to me from last couple of hours when i run this query
insert into payment set id ='13914', amount ='48.00', discount ='0.00',
total ='48.00', fees ='2', charges ='', staus ='2'
The value 48.00 saves in db column as just 48. db column type is double.
Your data is stored correctly. 48 == 48.00 when you use DOUBLE.
When you retrieve your data try
SELECT ROUND(amount,2) amount,
ROUND(discount, 2) discount
FROM payment
if you really have to see the .00 at the end of your numbers.
And please, please, for the good of the profession and your future users, learn how floating point numbers work.
Easily found in docs:
Because floating-point values are approximate and not stored as exact values, attempts to treat them as exact in comparisons may lead to problems. They are also subject to platform or implementation dependencies.
Further more:
Attempts to treat floating-point values as exact in comparisons may lead to problems. They are also subject to platform or implementation dependencies. The FLOAT and DOUBLE data types are subject to these issues. For DECIMAL columns, MySQL performs operations with a precision of 65 decimal digits, which should solve most common inaccuracy problems.
So rather use DECIMAL
SELECT ROUND(amount,2) amount,
ROUND(discount, 2) discount
FROM payment