# Assignment - More Randomness

Regardless if you have the simple or advanced DNA/Gene algorithm, I want you to make some modifications.

For those of you that have kept the simple algorithm: Add one more level of mixing into your algorithm. Get creative and see if you can find some other way of mixing the DNA’s instead of just combining the two halves.

For those of you that built the advanced algorithm: I mentioned in the last video that you can implement even more randomness to spice things up even more. That’s exactly what I want you to do.

Take the random number we calculated in the previous video, and use it to select one of the pairs that will get an extra randomness treatment. Then generate a new, 2 digit, random number and set it as that pair. That DNA pair will now be completely random, independent from any parent.

1 Like

Hey guys, my DNA string is 18 digits long so i used uint9 which I’m not sure is allowed. Remix threw an error which i have screen shotted below. Is there a way around this or should i shorten my DNA string?

``````function mixDna(uint256 _dadDNA, uint256 _mumDNA) internal view returns(uint256){
uint256[9] memory geneArray;
//sudo random number
uint9 random = uint9(uint256(keccak256(block.timestamp, block.difficulty))%511); //binary between 000000000-111111111

uint256 index = 8;
for(i = 0; i <= 256; i=i*2){ //1, 2, 4, 8, 16, 32, 64, 128, 256 = 9 pairs
if(random & i != 0){
geneArray[index] = uint9( _mumDNA % 100);
}else{
geneArray[index] = uint9( _dadDNA % 100);
}
_mumDNA = _mumDNA / 100;//removing the last two digits by moving the decimal point
index = index -1;
}
uint256 newGene;
for(i = 0; i < 9; i++){
newGene = newGene + geneArray[i];
if(i != 8){
newGene = newGene *100;
}
}
return newGene;
}
``````

1 Like

Hey @ol_frank uint9 is not allow.
From solidity docs : https://docs.soliditylang.org/en/v0.5.3/types.html
Read directly documentation is a very fast way to improve and understand from the base.

1 Like

Can you give me a hint on how to use the random number to determine which position of the newGene should be random as well? I can’t fully grasp how to do that.

Well, in my case i choose like the last digit of DNA to have it random. So it is like special stuff not coming from dad or mum. Example for 2 digit random number :

``````    function randomNum() returns (uint256){
uint256 randNumber = now % 100;
return randNumber
}

``````

Then you just add this result to the end of DNA like a special trait

I’ve kept the simple algorithm and added a completely random animation.

``````function _mixDna(uint256 _dadDna, uint256 _mumDna)
internal
view
returns (uint256)
{
uint256 mumPart = _mumDna % 100000000;

uint256 newDna = (dadPart * 100000000) + mumPart;

// Make animation completely Random I have implemented 1-7 types so I'll limit to that

uint8 random = uint8(block.timestamp % 7) + 1;

uint256 removeBit = newDna % 100;

newDna = (newDna - removeBit) + (random * 10) + 1;

return newDna;
}
``````
1 Like

Hello I have a question about Filip’s dna mixing algorithm.
I don’t understand why he uses 8 bits.

His cat DNA looks like this: 10, 13, 96, 10, 1, 1, 13, 13, 1, 1
Notice that there are 4 pairs for colors, 5 pairs for cattributes, and 1 pair for the last unknown digit. Therefore, there are 10 pairs in total.
However, in the video he used 8 bits. What’s also interesting is that some part of the DNA have only 1 digit. So diving by 100 and multiplying by 100 shouldn’t always work.

I don’t understand why and how it works.

DNA mixing code
``````function _mixDna(uint256 _dadDna, uint256 _mumDna) internal view returns(uint256){
uint256[8] memory geneArray;
uint8 random = uint8( block.timestamp % 255 );
uint i;
uint256 index = 7;
for(i = 1; i ＜= 128; i *= 2){
if(random & i != 0){
geneArray[index] = uint8(_mumDna % 100);
}else{
}
_mumDna /= 100;
index -= 1;
}
uint256 newGene;
for(i = 0; i < 8; i++){
newGene += geneArray[i];
if(i != 7){
newGene *= 100;
}
}
return newGene;
}
``````

@kenn.eth

2 Likes

After a few hours of work, I think I got it:

``````function _mixDna(uint256 _dadDna, uint256 _mumDna) internal view returns(uint256 newGene){
uint256[] memory geneArray = new uint256[](10);
uint8[10] memory digitControl = [100, 100, 100, 100, 10, 10, 10, 100, 10, 10];
uint16 random = uint16(uint256(keccak256(abi.encodePacked(block.timestamp, block.difficulty))) % 65536);
uint16 i;
uint16 index = 10;
for(i = 1; i <= 512; i = i * 2){
index = index - 1;
if(index == random % 10){
geneArray[index] = (_mumDna % digitControl[index] + _dadDna % digitControl[index]) / 2;
}else if(random & i != 0){
geneArray[index] = _mumDna % digitControl[index];
}else{
}
_mumDna /= digitControl[index];
}
for(i = 0; i < 10; i++){
newGene += geneArray[i];
if(i != 9){
newGene *= digitControl[i+1];
}
}
}
``````

Feature:

1. The random variable is more random. It takes `block.timestamp` and `block.difficulty` as parameters and hash it. Idea from @ol_frank.
2. Compatible with one digit gene.
3. When `index` is equal to the last digit of `random`, it takes average of dad gene and mum gene. This can happen only once in the for loop.

Full code: https://github.com/REGO350/nftgame

3 Likes

Hey @REGO350 ! There is many ways to mix DNA, some more complex than other. What we are doing here is to take parth of both DNA’s and mix it. But this way will not create similar cats that share some Attributes from parents. The form we mix, will depend on your styles and number of Attriubtes that act on the DNA. Lets say that is somethin thatg you can think of how you want to mix it. Depending on your style set.

1 Like

Hello this is my solution. Its simple but works if i is even the part for the number (example 10)of Dad dna wins and in the next count mom dna will win and then dad dna wins until the count is finished. I prefer not to make something very complicated because i understand is much better to use real randomness from oracles
My new code for _mixDna

``````function _mixDna(uint256 _dadDna, uint256 _mumDna) internal pure returns (uint256){
uint256 mod= 10000000000000000;

uint256 div= 100000000000000;

uint256 newDna= 0;

uint i;

for (i=1; i<=8; i++){

}

else { // _mumDna wins

newDna = (newDna*100)+((_mumDna%mod)/div);

}

mod = mod/100;

div = div/100;

}

return newDna;

}

``````

first pair of cats

second pair of cats

children

3 Likes

Hi all,

I have a question about an error I get. See the screenshot down below:

I tried several variations on the visibility of the getKitty function but can not solve it.

Here is my code:

Can someone tell me what I’ve been missing?

``````// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

import "./IERC721.sol";
import "../node_modules/@openzeppelin/contracts/access/Ownable.sol";

contract Kittycontract is IERC721, Ownable {

uint256 public constant CREATION_LIMIT_GEN0 = 10;
string private constant tokenName = "ThomasKitties";
string private constant tokenSymbol = "TM";

bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

struct Kitty {
uint256 genes;
uint64 birthTime;
uint32 mumId;
uint16 generation;
}

event Birth(
uint256 kittenId,
uint256 mumId,
uint256 genes
);

Kitty[] kitties;

mapping (uint256 => address) public kittyIndexToApproved;

uint256 public gen0Counter;

function breed(uint256 _dadId, uint256 _mumId) public returns (uint256) {
require(_owns(msg.sender, _dadId), "The user doesn't own the token");
require(_owns(msg.sender, _mumId), "The user doens't own the token");

( uint256 mumDna,,,,uint256 MumGeneration ) = getKitty(_mumId);

uint256 kidGen = 0;
kidGen = MumGeneration + 1;
kidGen /= 2;
} else if (DadGeneration > MumGeneration){
kidGen /= 2;
} else {
kidGen = MumGeneration + 1;
}

}

function supportsInterface(bytes4 _interfaceId) external pure returns (bool){
return (_interfaceId == _INTERFACE_ID_ERC721 || _interfaceId == _INTERFACE_ID_ERC165);
}

safeTransferFrom(_from, _to, _tokenId, "");
}

function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory _data) public override {
require( _isApprovedOrOwner(msg.sender, _from, _to, _tokenId) );
_safeTransfer(_from, _to, _tokenId, _data);
}

// function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory _data) public override {
//     require( _isApprovedOrOwner(msg.sender, _from, _to, _tokenId) );
//     _safeTransfer(_from, _to, _tokenId, _data);
// }

function _safeTransfer(address _from, address _to, uint256 _tokenId, bytes memory _data) internal {
_transfer(_from, _to, _tokenId);
require( _checkERC721Support(_from, _to, _tokenId, _data) );
}

require(_isApprovedOrOwner(msg.sender, _from, _to, _tokenId));
// require(msg.sender == _from || _approvedFor(msg.sender, _tokenId) || isApprovedForAll(_from, msg.sender));
// require(_owns(_from, _tokenId));
// require(tokenId < kitties.length);

_transfer(_from, _to, _tokenId);
}

function approve(address _to, uint256 _tokenId) public override {
require(_owns(msg.sender, _tokenId));

_approve(_tokenId, _to);
emit Approval(msg.sender, _to, _tokenId);
}

function setApprovalForAll(address operator, bool approved) public override{
require(operator != msg.sender);

_operatorApprovals[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}

function getApproved(uint256 tokenId) public view override returns (address){
require(tokenId < kitties.length); //Token must exist

return kittyIndexToApproved[tokenId];
}

return _operatorApprovals[owner][operator];
}

function getKitty(uint256 _id) external view returns(
uint256 genes,
uint256 birthTime,
uint256 mumId,
uint256 generation
)
{
Kitty storage kitty = kitties[_id];

birthTime = uint256(kitty.birthTime);
mumId = uint256(kitty.mumId);
generation = uint256(kitty.generation);
genes = kitty.genes;
}

function createKittyGen0(uint256 _genes) public onlyOwner returns (uint256){
require(gen0Counter < CREATION_LIMIT_GEN0);

gen0Counter++;

// Gen0 have no owners they are own by the contract
return _createKitty(0, 0, 0, _genes, msg.sender);

}

function _createKitty(
uint256 _mumId,
uint256 _generation,
uint256 _genes,
) public returns (uint256) {
Kitty memory _kitty = Kitty({
genes: _genes,
birthTime: uint64(block.timestamp),
mumId: uint32(_mumId),
generation: uint16(_generation)
});

// uint256 newKittenId = kitties.push(_kitty) -1;
kitties.push(_kitty);
uint256 newKittenId = kitties.length - 1;

emit Birth(_owner, newKittenId, _mumId, _dadId, _genes);

return newKittenId;
}

function balanceOf(address _owner) external view override returns (uint256 balance){
return ownershipTokenCount[_owner];
}

function totalSupply() external view override returns (uint){
return kitties.length;
}

function name() external pure override returns (string memory){
}

function symbol() external pure override returns (string memory){
}

function ownerOf(uint256 _tokenId) external view override returns (address owner){
return kittyIndexToOwner[_tokenId];
}

function transfer(address _to, uint256 _tokenId) external override {
require(_owns(msg.sender, _tokenId));

_transfer(msg.sender, _to, _tokenId);

}

ownershipTokenCount[_to]++;

kittyIndexToOwner[_tokenId] = _to;

ownershipTokenCount[_from]--;
delete kittyIndexToApproved[_tokenId];
}

emit Transfer(_from, _to, _tokenId);
}

function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) {
return kittyIndexToOwner[_tokenId] == _claimant;
}

function _approve(uint256 _tokenId, address _approved) internal {
kittyIndexToApproved[_tokenId] = _approved;
}

function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) {
return kittyIndexToApproved[_tokenId] == _claimant;
}

function _checkERC721Support(address _from, address _to, uint256 _tokenId, bytes memory _data) internal returns (bool){
if( !_isContract(_to) ){
return true;
}
//Call on ERC721Received in the _to contract
//Check return value
}

function _isContract(address _to) view internal returns (bool){
uint32 size;
assembly{
size := extcodesize(_to)
}
return size > 0;
}

require(_tokenId < kitties.length); //Token must exist
require(_owns(_from, _tokenId)); //From owns the token

//msg.sender is from OR spender is approved for tokenId OR spender is operator for from
return (_spender == _from || _approvedFor(_spender, _tokenId) || isApprovedForAll(_from, _spender));
}
function _mixDna(uint256 _dadDna, uint256 _mumDna) internal returns (uint256){
//dadDna: 11 22 33 44 55 66 77 88
//momDna: 88 77 66 55 44 33 22 11

uint256 firsthalf = _dadDna/ 100000000; //11223344
uint256 secondhalf = _mumDna % 100000000; //44332211

uint256 newDna = firsthalf * 100000000;
newDna = newDna + secondhalf; //which makes 1122334444332211
return newDna;
}

}

``````
1 Like

Hey @thomascarl, hope you are ok.

Have you tried to change its visibitily from external to public or internal for example?

Carlos Z

Hi Carlos,

Thanks for your quick response. I changed the visibility to public and added pure to the _mixDna function. I now have the following error:

1 Like

hey @thomascarl ! I notice that in your breed function you are using returns (uint256) on definition but not returning anything at end of the function. So just make sure to return the id for example if is need or not return anything is also ok. Use returns in case you want to use it for something else.

2 Likes

I’ve built the advanced breeding algorithm. Have a look at my `_mixGenes` function in my code below.

## Code

Kitties.sol
``````pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract Kitties is ERC721Enumerable, Ownable {
struct Kitty {
uint256 genes;
uint64 birthTime;
uint32 mumId;
uint16 generation;
}
Kitty[] private _kitties;

// Cap of how many generation 0 kitties can be created.
uint8 public constant GEN0_CAP = 10;
uint8 private _gen0Counter;

constructor() ERC721("Kitties", "KITS") {}

event Birth(
uint256 indexed kittyId,
uint256 mumId,
uint256 genes
);

// Breads a new kitty from two other kitties.
function breed(uint256 mumId, uint256 dadId) public {
// '_isApprovedOrOwner' includes check whether token exists
require(
_isApprovedOrOwner(msg.sender, mumId) &&
"Unauthorized"
);

Kitty storage mum = _kitties[mumId];

}

// Creates a generation 0 kitty.
function createKittyGen0(uint256 genes) public onlyOwner {
require(
_gen0Counter <= GEN0_CAP,
"All generation 0 kitties have already been created."
);
_gen0Counter++;
_createKitty(0, 0, 0, genes, owner());
}

// Returns how many generation 0 kitties have already been created.
function countKittiesGen0() public view returns (uint256) {
return uint256(_gen0Counter);
}

// Returns 'kittyId' kitty data.
function getKitty(uint256 kittyId)
public
view
returns (
uint256 genes,
uint256 birthTime,
uint256 mumId,
uint256 generation
)
{
require(_exists(kittyId), "Nonexistent");
Kitty storage kitty = _kitties[kittyId];

genes = kitty.genes;
birthTime = kitty.birthTime;
mumId = kitty.mumId;
generation = kitty.generation;
}

// ----- NONPUBLIC FUNCTIONS -----

function _mixGeneration(uint16 generation1, uint16 generation2)
internal
pure
returns (uint16)
{
return (generation1 + generation2) / 2 + 1;
}

function _mixGenes(uint256 genes1, uint256 genes2)
internal
view
returns (uint256)
{
// example genes: 20203001003511
// in 7 parts: 20 20 300 100 35 1 1
uint256 mixedGenes;
uint16[7] memory mixedGenesParts;
uint8 index = 6;

// the binary representation of this random number (0-255) decides which parts to take from genes1 and which from genes2
uint8 randomBinary = uint8(block.timestamp);
uint16 factor;

// inherit 'mixedGenesParts' from parents 'genes1' and 'genes2'
for (uint8 i = 0; i <= 6; i++) {
if (index == 3 || index == 2) {
factor = 1000;
} else if (index == 6 || index == 5) {
factor = 10;
} else {
factor = 100;
}

if ((randomBinary & maskBinary) == 0) {
mixedGenesParts[index] = uint16(genes1 % factor);
} else {
mixedGenesParts[index] = uint16(genes2 % factor);
}

if (i != 6) {
genes1 /= factor;
genes2 /= factor;
index--;
}
}

// add random value for one random genes part
uint8 randomPart = randomBinary % 7;
uint16 randomPartValue;
if (randomPart == 0 || randomPart == 1) {
randomPartValue = 10 + (randomBinary % 81);
} else if (randomPart == 2) {
randomPartValue = 100 + randomBinary;
} else if (randomPart == 3) {
randomPartValue = uint16(10**(randomBinary % 3));
} else if (randomPart == 4) {
randomPartValue = 10 + (randomBinary % 46);
} else if (randomPart == 5 || randomPart == 6) {
randomPartValue = randomBinary % 4;
}
mixedGenesParts[randomPart] = randomPartValue;

// assemble 'mixedGenes'
for (uint8 i = 0; i <= 6; i++) {
mixedGenes += mixedGenesParts[i];
if (i != 6) {
if (i == 1 || i == 2) {
factor = 1000;
} else if (i == 4 || i == 5) {
factor = 10;
} else {
factor = 100;
}
mixedGenes *= factor;
}
}

return mixedGenes;
}

function _createKitty(
uint256 mumId,
uint256 generation,
uint256 genes,
) internal {
Kitty memory newKitty = Kitty({
genes: genes,
birthTime: uint64(block.timestamp),
mumId: uint32(mumId),
generation: uint16(generation)
});
_kitties.push(newKitty);

uint256 newKittyId = _kitties.length - 1;
require(newKittyId == uint256(uint32(newKittyId)));
emit Birth(
owner,
newKittyId,
uint256(newKitty.mumId),
newKitty.genes
);

_safeMint(owner, newKittyId);
}
}

``````
2 Likes

Got it from here:

_mixDna function

``````    internal

view

returns (uint256)

{

uint256[8] memory geneArray;

//pseudo-random: Not used for betting and monetary stuff

//binary 8bit between 00000000 to 11111111

uint8 random = uint8(

uint256(

keccak256(abi.encodePacked(block.timestamp, block.difficulty))

) % 255

);

//1, 2, 4, 8, 16, 32, 64, 128, loop through 8 times

//values of the 8 numbers above in binary

//00000001, 00000010, 00000100, 00001000,

//00010000, 00100000, 01000000, 10000000

//bitwise operator &

uint256 i = 1;

uint256 index = 7;

for (i = 1; i <= 128; i *= 2) {

if (random & i != 0) {

geneArray[index] = uint8(_mumDna % 100); //last pair

} else {

}

//now remove last pair from dna

_mumDna /= 100;

//reduce index to set position to previous (e.g. from 7 to 6)

index--;

}

//create DNA into a full number

uint256 newGene;

for (i = 0; i < 8; i++) {

newGene += geneArray[i]; //add first pair to mewGene

if (i != 7) {

//to not add 2 zeroes after the last pair

newGene *= 100; //adds two zeroes (00), at the end of each pair

}

}

return newGene;

}
``````
1 Like

Mixing DNA randomness.

``````function _mixDna(uint256 dadDNA, uint256 momDNA) internal view returns (uint256) {
{

uint256[8] memory geneArray;

//pseudo-random: Not used for betting and monetary stuff

//binary 8bit between 00000000 to 11111111

uint8 random = uint8(

uint256(

keccak256(abi.encodePacked(block.timestamp, block.difficulty))

) % 255

);

uint256 i = 1;

uint256 index = 7;

for (i = 1; i <= 128; i *= 2) {

if (random & i != 0) {

geneArray[index] = uint8(momDNA % 100); //last pair

} else {

}

//now remove last pair from dna

momDNA /= 100;

//reduce index to set position to previous (e.g. from 7 to 6)

index--;

}

//create DNA into a full number

uint256 newGene;

for (i = 0; i < 8; i++) {

newGene += geneArray[i]; //add first pair to mewGene

if (i != 7) {

//to not add 2 zeroes after the last pair

newGene *= 100; //adds two zeroes (00), at the end of each pair

}

}

return newGene;

}
}
``````

Hiya!
From the below code, I’m getting an error in Remix -

The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.

``````//SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.0;

contract Test{

function _mixDNA(uint dadDNA,uint mumDNA) public view returns(uint){
uint[8] memory geneArray;
uint8 random = uint8(block.timestamp % 256); //0-255
uint index = 7;

for(uint i = 1 ; i <= 128 ; i = i*2){
if(random & i != 0){
geneArray[index] = mumDNA % 100;
}
else{

}
mumDNA = mumDNA / 100;
index = index-1;
}

uint newGene = 0;
for(uint i = 0 ; i < 8 ; i++){
newGene = newGene + geneArray[i];
if(i != 7){
newGene = newGene * 100;
}
}
return newGene;
}
}

//1122334455667788,8877665544332211
``````

Still getting the same error with this function header-

``````     function _mixDNA(uint dadDNA,uint mumDNA) public payable returns(uint){

``````

But the thing is…with compiler version 0.5.12 it’s working fine.
@kenn.eth how can I resolve this one.

Edit: That’s the error in the truffle

``````Uncaught Error: Returned error: VM Exception while processing transaction: revert
at evalmachine.<anonymous>:0:10
at sigintHandlersWrap (vm.js:273:12)
at Script.runInContext (vm.js:140:14)
at runScript (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\console.js:329:1)
at Console.interpret (C:\Users\HP\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\console.js:344:1)
at bound (domain.js:413:15)
at REPLServer.runBound [as eval] (domain.js:424:12)
at REPLServer.onLine (repl.js:817:10)
at REPLServer.emit (events.js:315:20)
at REPLServer.EventEmitter.emit (domain.js:467:12)
at REPLServer.self._ttyWrite (repl.js:907:9) {
data: {
'0x582bdafd2952d384db69a303cbfa0d88a3a90ecb344bcd9a7babe11d5bcb1792': {
error: 'revert',
program_counter: 12546,
return: '0x4e487b710000000000000000000000000000000000000000000000000000000000000011'
},
stack: 'RuntimeError: VM Exception while processing transaction: revert\n' +
'    at Function.RuntimeError.fromResults (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\utils\\runtimeerror.js:94:13)\n' +
'    at BlockchainDouble.processBlock (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\blockchain_double.js:627:24)\n' +
name: 'RuntimeError'
},
hijackedStack: 'Error: Returned error: VM Exception while processing transaction: revert\n' +
'    at Object.ErrorResponse (C:\\Users\\HP\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\node_modules\\web3-core-helpers\\lib\\errors.js:28:1)\n' +
'    at C:\\Users\\HP\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\node_modules\\web3\\node_modules\\web3-core-requestmanager\\lib\\index.js:303:1\n' +
'    at C:\\Users\\HP\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\packages\\provider\\wrapper.js:107:1\n' +
'    at IncomingMessage.emit (events.js:327:22)\n' +
'    at IncomingMessage.EventEmitter.emit (domain.js:529:15)\n' +
}
``````
2 Likes

Assignment:

``````//SPDX-License-Identifier: UNLICENSED
pragma solidity 0.5.12;

contract Test{

function _mixDNA(uint dadDNA,uint mumDNA) public view returns(uint){
uint[8] memory geneArray;
uint8 random = uint8(block.timestamp % 256); //0-255
uint index = 7;

for(uint i = 1 ; i <= 128 ; i = i*2){
if(random & i != 0){
geneArray[index] = mumDNA % 100;
}
else{

}
mumDNA = mumDNA / 100;
index = index-1;
}

for(uint i = 0 ; i < 4 ; i++){
uint8 pos = uint8(block.timestamp % 8); //0-7
uint8 newRandom = uint8(block.timestamp % 100);//0-99
geneArray[pos] = newRandom;
}

uint newGene = 0;
for(uint i = 0 ; i < 8 ; i++){
newGene = newGene + geneArray[i];
if(i != 7){
newGene = newGene * 100;
}
}
return newGene;
}
}

//1122334455667788,8877665544332211
``````

Hey @tanu_g, hope you are well.

I have managed to run your _mixDNA function with solidity 0.8.0, the problem is on the amount of steps for the loop iteration with the variable `i`. For a 16digits DNA like yours, the amount of iterations might not need to be the same, (instead of `i <= 128`, yours work with `i <= 64`).

The problem comes from the index variable, the last iteration will fail cuz `index` should be always a positive number (uint), but for each iteration it will decrease one and at the last iteration it will run into a negative number.

Carlos Z

3 Likes