Skip to content

Commit 2a92f47

Browse files
committed
Assets initialized
1 parent 58713b8 commit 2a92f47

19 files changed

+21266
-2
lines changed

Diff for: .gitignore

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
node_modules
2+
.env
3+
coverage
4+
coverage.json
5+
typechain
6+
typechain-types
7+
8+
# Hardhat files
9+
cache
10+
artifacts
11+
12+
13+
node_modules
14+
.env
15+
coverage
16+
coverage.json
17+
typechain
18+
typechain-types
19+
20+
# Hardhat files
21+
cache
22+
artifacts
23+

Diff for: .vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"solidity.defaultCompiler": "localNodeModule"
3+
}

Diff for: Lock.js

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
const {
2+
time,
3+
loadFixture,
4+
} = require("@nomicfoundation/hardhat-network-helpers");
5+
const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs");
6+
const { expect } = require("chai");
7+
8+
describe("Lock", function () {
9+
// We define a fixture to reuse the same setup in every test.
10+
// We use loadFixture to run this setup once, snapshot that state,
11+
// and reset Hardhat Network to that snapshot in every test.
12+
async function deployOneYearLockFixture() {
13+
const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
14+
const ONE_GWEI = 1_000_000_000;
15+
16+
const lockedAmount = ONE_GWEI;
17+
const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS;
18+
19+
// Contracts are deployed using the first signer/account by default
20+
const [owner, otherAccount] = await ethers.getSigners();
21+
22+
const Lock = await ethers.getContractFactory("Lock");
23+
const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
24+
25+
return { lock, unlockTime, lockedAmount, owner, otherAccount };
26+
}
27+
28+
describe("Deployment", function () {
29+
it("Should set the right unlockTime", async function () {
30+
const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);
31+
32+
expect(await lock.unlockTime()).to.equal(unlockTime);
33+
});
34+
35+
it("Should set the right owner", async function () {
36+
const { lock, owner } = await loadFixture(deployOneYearLockFixture);
37+
38+
expect(await lock.owner()).to.equal(owner.address);
39+
});
40+
41+
it("Should receive and store the funds to lock", async function () {
42+
const { lock, lockedAmount } = await loadFixture(
43+
deployOneYearLockFixture
44+
);
45+
46+
expect(await ethers.provider.getBalance(lock.address)).to.equal(
47+
lockedAmount
48+
);
49+
});
50+
51+
it("Should fail if the unlockTime is not in the future", async function () {
52+
// We don't use the fixture here because we want a different deployment
53+
const latestTime = await time.latest();
54+
const Lock = await ethers.getContractFactory("Lock");
55+
await expect(Lock.deploy(latestTime, { value: 1 })).to.be.revertedWith(
56+
"Unlock time should be in the future"
57+
);
58+
});
59+
});
60+
61+
describe("Withdrawals", function () {
62+
describe("Validations", function () {
63+
it("Should revert with the right error if called too soon", async function () {
64+
const { lock } = await loadFixture(deployOneYearLockFixture);
65+
66+
await expect(lock.withdraw()).to.be.revertedWith(
67+
"You can't withdraw yet"
68+
);
69+
});
70+
71+
it("Should revert with the right error if called from another account", async function () {
72+
const { lock, unlockTime, otherAccount } = await loadFixture(
73+
deployOneYearLockFixture
74+
);
75+
76+
// We can increase the time in Hardhat Network
77+
await time.increaseTo(unlockTime);
78+
79+
// We use lock.connect() to send a transaction from another account
80+
await expect(lock.connect(otherAccount).withdraw()).to.be.revertedWith(
81+
"You aren't the owner"
82+
);
83+
});
84+
85+
it("Shouldn't fail if the unlockTime has arrived and the owner calls it", async function () {
86+
const { lock, unlockTime } = await loadFixture(
87+
deployOneYearLockFixture
88+
);
89+
90+
// Transactions are sent using the first signer by default
91+
await time.increaseTo(unlockTime);
92+
93+
await expect(lock.withdraw()).not.to.be.reverted;
94+
});
95+
});
96+
97+
describe("Events", function () {
98+
it("Should emit an event on withdrawals", async function () {
99+
const { lock, unlockTime, lockedAmount } = await loadFixture(
100+
deployOneYearLockFixture
101+
);
102+
103+
await time.increaseTo(unlockTime);
104+
105+
await expect(lock.withdraw())
106+
.to.emit(lock, "Withdrawal")
107+
.withArgs(lockedAmount, anyValue); // We accept any value as `when` arg
108+
});
109+
});
110+
111+
describe("Transfers", function () {
112+
it("Should transfer the funds to the owner", async function () {
113+
const { lock, unlockTime, lockedAmount, owner } = await loadFixture(
114+
deployOneYearLockFixture
115+
);
116+
117+
await time.increaseTo(unlockTime);
118+
119+
await expect(lock.withdraw()).to.changeEtherBalances(
120+
[owner, lock],
121+
[lockedAmount, -lockedAmount]
122+
);
123+
});
124+
});
125+
});
126+
});

Diff for: README.md

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,13 @@
1-
# Blockchain-Assets
2-
Creating a Blockchain Asset
1+
# Sample Hardhat Project
2+
3+
This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a script that deploys that contract.
4+
5+
Try running some of the following tasks:
6+
7+
```shell
8+
npx hardhat help
9+
npx hardhat test
10+
REPORT_GAS=true npx hardhat test
11+
npx hardhat node
12+
npx hardhat run scripts/deploy.js
13+
```

Diff for: contracts/Assets.sol

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
//This Script might not be just for lands or assets it might be things that have value and can be backed with a physical property
4+
//implement a loan system where can borrow and put there assests as a collatarel
5+
pragma solidity ^0.8.17;
6+
7+
error NotOwner();
8+
error NotenoughToken();
9+
error AssetNotForSale();
10+
error OnlyAdmin();
11+
12+
contract Assets {
13+
Deeds[] public assets;
14+
mapping(address=>Deeds) public ownersToDeeds;
15+
mapping(address=>uint)public addressOwnerCount;
16+
mapping(uint => address)public assetToAddressOwner;
17+
18+
event soldAsset(address formerOwner, uint assetId, address newOwner, uint time);
19+
20+
address owner;
21+
22+
constructor(){
23+
owner = msg.sender;
24+
}
25+
26+
struct Deeds {
27+
address payable _address;
28+
string location;
29+
uint geo_location;
30+
uint plot;
31+
uint value;
32+
uint time;
33+
bool sell;
34+
bool approved;
35+
}
36+
modifier onlyOwner() {
37+
if(msg.sender != owner) revert OnlyAdmin();
38+
_;
39+
}
40+
//Make Sure that the amount is sufficient an dthe asset is for sale
41+
modifier validator(uint _id){
42+
if(msg.value < assets[_id].value) revert NotenoughToken();
43+
if(assets[_id].sell != true) revert AssetNotForSale();
44+
_;
45+
//require(msg.value >= assets[_id].value, "Insuficient amount to obtain asset");
46+
//require(assets[_id].sell == true, "Asset is not for sale");
47+
// require(msg.sender == owner);
48+
//if (msg.sender != assets[_id]._address) revert NotOwner();
49+
}
50+
//This function creates ownership of an asset
51+
// might only be called by the onlyOwner modifier in future
52+
function getOwnership(string memory location, uint geo_location,uint plot, uint value) public{
53+
Deeds memory _deed = Deeds( payable(msg.sender),location, geo_location,plot,value,block.timestamp,false,false);
54+
assets.push(_deed);
55+
ownersToDeeds[msg.sender] = _deed;
56+
addressOwnerCount[msg.sender]++;
57+
assetToAddressOwner[assets.length-1] = msg.sender;
58+
}
59+
// this function exchanges an asset for its current value
60+
function buy(uint _id) public payable validator(_id){
61+
address _address = assets[_id]._address;
62+
(bool sent,) =_address.call{value: msg.value}("");
63+
require(sent);
64+
assets[_id].value = msg.value;
65+
transferOwnership(_id);
66+
emit soldAsset(_address,_id,msg.sender,block.timestamp);
67+
}
68+
//Transfers ownership of an asset and updates mappings and variables
69+
function transferOwnership(uint _id) private {
70+
address _address = assets[_id]._address;
71+
addressOwnerCount[_address]--;
72+
assets[_id]._address = payable(msg.sender);
73+
addressOwnerCount[msg.sender]++;
74+
assetToAddressOwner[_id] = msg.sender;
75+
ownersToDeeds[msg.sender] = assets[_id];
76+
assets[_id].sell = false;
77+
78+
}
79+
//This function approves the asset that is being entered, that it is legitimate ans true
80+
function ApproveAsset(uint _id)public onlyOwner{
81+
assets[_id].approved = true;
82+
}
83+
84+
function getAllAssets() public view returns(Deeds[] memory){
85+
return assets;
86+
}
87+
88+
//this function retreives owners assets
89+
function retrieveOwnersAssets(address _address)public view returns(uint[] memory){
90+
uint[] memory array = new uint[](addressOwnerCount[_address]);
91+
uint counter = 0;
92+
for (uint i = 0; i < assets.length; i++)
93+
{
94+
if(assetToAddressOwner[i] == _address){
95+
array[counter] = i;
96+
counter++;
97+
}
98+
} return array;
99+
}
100+
//mark asset as sellable
101+
function sellProperty(uint _id) public {
102+
if (msg.sender != assets[_id]._address) revert NotOwner();
103+
assets[_id].sell = true;
104+
}
105+
//create a function that updates the value of an asset
106+
function updateValue(uint _id)public{}
107+
108+
function inheritOwnership() public{}
109+
function partOwnership()public{}
110+
function giftOwnership()public{}
111+
}
112+

Diff for: contracts/Lock.sol

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.9;
3+
4+
// Uncomment this line to use console.log
5+
// import "hardhat/console.sol";
6+
7+
contract Lock {
8+
uint public unlockTime;
9+
address payable public owner;
10+
11+
event Withdrawal(uint amount, uint when);
12+
13+
constructor(uint _unlockTime) payable {
14+
require(
15+
block.timestamp < _unlockTime,
16+
"Unlock time should be in the future"
17+
);
18+
19+
unlockTime = _unlockTime;
20+
owner = payable(msg.sender);
21+
}
22+
23+
function withdraw() public {
24+
// Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal
25+
// console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);
26+
27+
require(block.timestamp >= unlockTime, "You can't withdraw yet");
28+
require(msg.sender == owner, "You aren't the owner");
29+
30+
emit Withdrawal(address(this).balance, block.timestamp);
31+
32+
owner.transfer(address(this).balance);
33+
}
34+
}

Diff for: deploy/01-Assets-deploy.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
const { ethers, network } = require("hardhat")
3+
const { developmentChains } = require("../helper-hh-config")
4+
const {verify} = require("../scripts/verify")
5+
6+
7+
module.exports.default = async ({deployments}) => {
8+
const {deploy,log} = deployments
9+
const accounts = await ethers.getSigners()
10+
const deployer = accounts[0].address
11+
12+
log("_____contract deploying________")
13+
const assets = await deploy("Assets", {
14+
from: deployer,
15+
args: [],
16+
log: true,
17+
waitConfirmations: network.config.blockConifrmations || 1,
18+
})
19+
log("_____contract deployed________")
20+
log(`***********verifying ${assets.address}**********`)
21+
22+
if(!developmentChains.includes(network.name)) {
23+
await verify(assets.address,[])
24+
}
25+
}

Diff for: deploy/01-Lock-deploy.js

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// We require the Hardhat Runtime Environment explicitly here. This is optional
2+
// but useful for running the script in a standalone fashion through `node <script>`.
3+
//
4+
// You can also run a script with `npx hardhat run <script>`. If you do that, Hardhat
5+
// will compile your contracts, add the Hardhat Runtime Environment's members to the
6+
// global scope, and execute the script.
7+
const hre = require("hardhat");
8+
9+
module.exports.default = async function() {
10+
const currentTimestampInSeconds = Math.round(Date.now() / 1000);
11+
const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
12+
const unlockTime = currentTimestampInSeconds + ONE_YEAR_IN_SECS;
13+
14+
const lockedAmount = hre.ethers.utils.parseEther("1");
15+
16+
const Lock = await hre.ethers.getContractFactory("Lock");
17+
const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
18+
19+
await lock.deployed();
20+
21+
console.log(
22+
`Lock with 1 ETH and unlock timestamp ${unlockTime} deployed to ${lock.address}`
23+
);
24+
}
25+
26+
// We recommend this pattern to be able to use async/await everywhere
27+
// and properly handle errors.
28+
// main().catch((error) => {
29+
// console.error(error);
30+
// process.exitCode = 1;
31+
// });

Diff for: deployments/localhost/.chainId

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
31337

0 commit comments

Comments
 (0)