Commit 84edd2a5 authored by Kirti's avatar Kirti

FlexiSwap

parents
Pipeline #1794 canceled with stages
node_modules
.env
coverage
coverage.json
typechain
typechain-types
.secret
#Hardhat files
cache
artifacts
File added
# Atomic Swap
This project implements HTLC based atomic swap between Ontology and Ethereum with an on chain bidding on the Ethereum chain.
Currently swap can be done only when order is initiated via Ontology and responded via Ethereum.
Stack used:
NodeJS: For creating a javascript environment that works as server
Express: For routing
MetaMask: Signing transactions
Hardhat : Compiling and deploying smart contracts
MongoDB Atlas: For storing the current bids in progress.
Languages used:
Solidity
Javascript
Deploy contracts using: npx hardhat run --network sepolia scripts/deployeth.js and deployont.js for ontology_testnet
1. npm install
2. Setup metamask wallet
3. Configure two networks in metamask:
ONTOLOGY TESTNET
Network name - Ontology TestNet
New RPC URL - https://polaris2.ont.io:10339
Chain ID - 5851
Currency symbol - ONT
Block explorer URL(Optional) - https://explorer.ont.io/testnet
GOERLI TESTNET
Network name - Goerli test network
New RPC URL - https://goerli.infura.io/v3/
Chain ID - 5
Currency symbol - GoerliETH
Block explorer URL(Optional) - https://goerli.etherscan.io
4. Run npm app.js
5. localhost:3000 -> For the platform
6. localhost:3000/txns -> For the order book
\ No newline at end of file
const express = require('express');
const morgan = require('morgan');
const mongoose = require('mongoose');
const txns = require('./models/txns');
const Web3 = require("web3");
var fs = require('fs');
// express app
const app = express();
// app.use(express.static(__dirname + '/public'));
app.listen(3000);
// connect to mongodb & listen for requests
const dbURI = "mongodb+srv://redkirti:Strong1234@cluster0.4oandf8.mongodb.net/orderbook?retryWrites=true&w=majority";
const connectionParams={
useNewUrlParser: true,
useUnifiedTopology: true
}
mongoose.connect(dbURI,connectionParams)
.then( () => {
console.log('Connected to the database ')
console.log('Listening on Port 3000')
})
.catch( (err) => {
console.error(`Error connecting to the database. n${err}`);
})
const ethNetwork = 'https://sepolia.infura.io/v3/069b7d73ec604e52a5092610c9f410ea';
const web3 = new Web3(new Web3.providers.HttpProvider(ethNetwork));
const web3ont = new Web3(new Web3.providers.HttpProvider('https://polaris2.ont.io:10339'));
async function func(hashlock){
var jsonFile = "artifacts/contracts/OntologyContract.sol/OntologyContract.json";
var parsed= JSON.parse(fs.readFileSync(jsonFile));
var abiONT = parsed.abi;
var jsonFile = "artifacts/contracts/EthereumContract.sol/EthereumContract.json";
var parsed= JSON.parse(fs.readFileSync(jsonFile));
var abiETH = parsed.abi;
var contract = await new web3.eth.Contract(abiETH, '0x16731AB4cE3af35c5774e42fA06eAefb481D1628');
var x = await contract.methods.orderList(hashlock).call();
var contractont = await new web3ont.eth.Contract(abiONT, '0x1C2a6c5EaF6bFCEeF3f52c0e5e6DC89F8756E5D9');
var y = await contractont.methods.orderList(hashlock).call();
return {'hashlock':hashlock, 'amountOnt': x['amount'], 'bidTimelock':timeConverter(x['bidTimelock'])};
}
function timeConverter(UNIX_timestamp){
var a = new Date(UNIX_timestamp * 1000);
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var year = a.getFullYear();
var month = months[a.getMonth()];
var date = a.getDate();
var hour = a.getHours();
var min = a.getMinutes();
var sec = a.getSeconds();
var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec ;
return time;
}
// register view engine
app.set('view engine', 'ejs');
// middleware & static files
app.use(express.static('public'));
app.use(express.urlencoded({ extended: true}));
app.use(morgan('dev'));
app.use((req, res, next) => {
res.locals.path = req.path;
next();
});
app.post('/txns', async (req, res) => {
console.log(req.body);
// const txn = new txns(req.body);
var obj = await func(req.body['hashlock']);
if(obj['amountOnt']!="0"){
const txn = new txns(obj);
txn.save().then((result) => {
res.send(result)
})
.catch((err) => {
console.log(err);
})
}
else{
console.log('Empty or time exceeded');
}
});
app.get('/txns', (req,res) => {
txns.find().then((result) => {
res.render('orderbook', {title: 'All Transactions', txns: result});
})
.catch((err) => {
console.log(err);
})
})
app.get('/', (req, res) => {
res.render('index');
});
// 404 page
app.use((req, res) => {
res.status(404).render('404', { title: '404' });
});
0xC6CD342cEba445bBfB98B9d5Da99c62B2B98CFbe - ONT
0x6EF8fd109f067F51f8ae25B41FD56b1a7b8f042B - ONT
0x8909Dff24b48790c9A0590F706Dc8f3B1709ce88 - ETH
ETH - 0xF47047A4df35aB1101E9C631d78732C98f5c38a7
ONT - 0xc64312F19324EED5587f83F8807b8F8ec85e8B08
\ No newline at end of file
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.16 <0.9.0;
contract EthereumContract {
enum Status {
Blank,
Initiated,
Locked, // ETH was locked by buyer
Set, //intitiator address set by buyer
Refunded, // ETH was refunded to buyer
Claimed // ETH was sucessfully claimed by order initiator
}
struct bidDetails {
address buyerOntAddress;
uint rate;
uint max;
uint locked;
uint timelock;
bytes32 hashlock2;
string secret;
bool claimed;
}
struct respondOrder {
address initiatorEthAddress;
address initiatorOntAddress;
address[] buyerEthAddress;
bytes32 hashlock;
bytes32 hashlock2;// Not required
uint amount;
uint refundTimelock;//Not required
uint bidTimelock;
string secret;
Status status;
mapping (address => bidDetails) bids; //indexed address is buyerEthAddress
}
mapping (bytes32 => respondOrder) public orderList; // hashlock => order data
uint timelockDuration = 600; // set to 600 seconds for testing purposes
uint bidtime = 300; //set to 300 seconds for testing
function getArr(bytes32 hashlock) public view returns (address[] memory) {
return orderList[hashlock].buyerEthAddress;
}
function getBids(bytes32 hashlock, address buyerEthAddress) public view returns(address, uint, uint, uint, uint, bytes32, string memory, bool) {
bidDetails storage t = orderList[hashlock].bids[buyerEthAddress];
return (t.buyerOntAddress, t.rate, t.max, t.locked, t.timelock, t.hashlock2, t.secret, t.claimed);
}
function initiateOrder(bytes32 hashlock, address initiatorOntAddress, uint amount) public payable{
if((orderList[hashlock].status!=Status.Blank) && (block.timestamp > orderList[hashlock].bidTimelock + 1200)){
delete orderList[hashlock];
}
require(orderList[hashlock].status == Status.Blank, "Not a fresh hashlock");
require(msg.value == 50000000000000, "Not provided the exact dex fees");
orderList[hashlock].bidTimelock = block.timestamp + bidtime;
orderList[hashlock].status = Status.Initiated;
orderList[hashlock].amount = amount;
orderList[hashlock].initiatorEthAddress = msg.sender;
orderList[hashlock].initiatorOntAddress = initiatorOntAddress;
// Can remove this and from struct as well
orderList[hashlock].hashlock = hashlock;
}
function bid(bytes32 hashlock, address buyerOntAddress, uint rate, uint max) public{
require(orderList[hashlock].status == Status.Initiated || orderList[hashlock].status==Status.Locked, "Transaction in Invalid State");
require(block.timestamp<=orderList[hashlock].bidTimelock, "Bidding Period Ended");
// If no one bid for the exchange control won't come here
orderList[hashlock].buyerEthAddress.push(msg.sender);
orderList[hashlock].bids[msg.sender].buyerOntAddress = buyerOntAddress;
orderList[hashlock].bids[msg.sender].rate = rate;
orderList[hashlock].bids[msg.sender].max = max;
orderList[hashlock].status = Status.Locked;
}
function lock(bytes32 hashlock, bytes32 hashlock2) public payable{
// Find the calling address belongs to buyerEthAddress array, otherwise anyone can enter
require(orderList[hashlock].status == Status.Locked || orderList[hashlock].status == Status.Set, "Not in locked or Set state");
require(orderList[hashlock].bids[msg.sender].buyerOntAddress != address(0), "You have not bidded");
orderList[hashlock].bids[msg.sender].hashlock2 = hashlock2;
orderList[hashlock].bids[msg.sender].locked = msg.value;
orderList[hashlock].bids[msg.sender].timelock = block.timestamp + timelockDuration;
orderList[hashlock].status = Status.Set;
}
function claimEth(bytes32 hashlock, address[] memory buyerEthAddress, string[] memory secret) public{
require(orderList[hashlock].initiatorEthAddress == msg.sender, "Not the initiator");
require(orderList[hashlock].status == Status.Set, "Order status should be Set");
for (uint i = 0; i < buyerEthAddress.length; ++i) {
require(orderList[hashlock].bids[buyerEthAddress[i]].timelock>block.timestamp, "Claim time ended");
require(sha256(abi.encodePacked(secret[i])) == orderList[hashlock].bids[buyerEthAddress[i]].hashlock2, "Secret does not match the hashlock");
payable(msg.sender).transfer(orderList[hashlock].bids[buyerEthAddress[i]].locked);
orderList[hashlock].bids[buyerEthAddress[i]].claimed = true;
orderList[hashlock].bids[buyerEthAddress[i]].secret = secret[i];
}
orderList[hashlock].status = Status.Claimed;
}
function refundEth (bytes32 hashlock) public {
require(orderList[hashlock].bids[msg.sender].claimed == false , "Already claimed");
require((block.timestamp >= orderList[hashlock].bids[msg.sender].timelock) || (orderList[hashlock].status == Status.Claimed), "Timelock is not over or not yet claimed");
require((orderList[hashlock].status == Status.Set) || (orderList[hashlock].status == Status.Claimed), "Order should be in Set or claimed state for refund");
payable(msg.sender).transfer(orderList[hashlock].bids[msg.sender].locked);
}
}
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.16 <0.9.0;
contract OntologyContract {
enum Status {
Blank,
Locked, // ONT tokens were locked by initiator
Set,
Refunded, // ONT was refunded to buyer
Claimed // ONT was sucessfully claimed by order initiators
}
struct bidDetails {
address buyerEthAddress;
uint locked;
bytes32 hashlock2;
}
struct initiatedOrder {
address initiatorOntAddress;
address initiatorEthAddress;
address[] buyerOntAddress;
bytes32 hashlock;
uint amountOnt;
uint refundTimelock;
string secret;
Status status;
mapping (address => bidDetails) bids;
}
mapping (bytes32 => initiatedOrder) public orderList; // hashlock => order data
uint timelockDuration = 900; // set to 900 seconds for testing purposes
function getArr(bytes32 hashlock) public view returns (address[] memory) {
return orderList[hashlock].buyerOntAddress;
}
function getBids(bytes32 hashlock, address buyerOntAddress) public view returns(address, uint, bytes32) {
bidDetails storage t = orderList[hashlock].bids[buyerOntAddress];
return (t.buyerEthAddress, t.locked, t.hashlock2);
}
//ALICE HAS TO CHECK WHETHER BIDDING HAS FINISHED
function lockandset(bytes32 hashlock, string memory secret, bytes32[] memory hashlocks, address[] memory buyerOntAddress, address[] memory buyerEthAddress, uint[] memory amount) public payable{
if((orderList[hashlock].status!=Status.Blank) && ((block.timestamp-orderList[hashlock].refundTimelock)>120)){
delete orderList[hashlock];
}
require(orderList[hashlock].status==Status.Blank, "Already in Use");
require(sha256(abi.encodePacked(secret)) == hashlock, "Secret does not match the hashlock");
// Only initiator can reach here
orderList[hashlock].refundTimelock = block.timestamp + timelockDuration;
orderList[hashlock].initiatorOntAddress = msg.sender;
for(uint i = 0; i<hashlocks.length; ++i){
orderList[hashlock].buyerOntAddress.push(buyerOntAddress[i]);
orderList[hashlock].bids[buyerOntAddress[i]].buyerEthAddress = buyerEthAddress[i];
orderList[hashlock].bids[buyerOntAddress[i]].hashlock2 = hashlocks[i];
orderList[hashlock].bids[buyerOntAddress[i]].locked = amount[i];
}
// Check if locked amount is sum of all amounts in individual accounts
uint totalamount = 0;
for(uint j = 0; j<buyerOntAddress.length; ++j){
totalamount += orderList[hashlock].bids[buyerOntAddress[j]].locked;
}
require(totalamount <= msg.value, "Not enough amount locked");
orderList[hashlock].amountOnt = msg.value;
orderList[hashlock].status = Status.Set;
}
function claimOnt(bytes32 hashlock, string memory secret) public {
require(orderList[hashlock].status == Status.Set, "Order status should be locked");
require(orderList[hashlock].bids[msg.sender].buyerEthAddress != address(0), "Initiator didn't choose you or haven't bidded");
require(sha256(abi.encodePacked(secret)) == orderList[hashlock].bids[msg.sender].hashlock2, "Secret does not match the hashlock");
payable(msg.sender).transfer(orderList[hashlock].bids[msg.sender].locked);
orderList[hashlock].amountOnt -= orderList[hashlock].bids[msg.sender].locked;
}
function refundOnt (bytes32 hashlock) public {
require(orderList[hashlock].status == Status.Set, "Order status should be locked");
require(orderList[hashlock].initiatorOntAddress == msg.sender, "Can only be perfomed by order initiator");
require(block.timestamp >= orderList[hashlock].refundTimelock, "Timelock is not over");
orderList[hashlock].status = Status.Refunded;
payable(msg.sender).transfer(orderList[hashlock].amountOnt);
//Transaction Finished. Make the hash ready for probable other txn
delete orderList[hashlock];
}
}
require("@nomicfoundation/hardhat-toolbox");
const fs = require('fs');
const privateKey = fs.readFileSync(".secret").toString().trim();
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: {
version: "0.8.17",
settings: {
optimizer: {
enabled: true,
runs: 200
}
}
},
networks: {
hardhat: {},
ontology_testnet: {
url: "http://polaris2.ont.io:20339",
chainId: 5851,
accounts: [privateKey],
allowUnlimitedContractSize: true
},
goerli: {
url: "https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161",
accounts: [privateKey],
chainId: 5,
allowUnlimitedContractSize: true
},
sepolia: {
url: "https://sepolia.infura.io/v3/069b7d73ec604e52a5092610c9f410ea",
accounts: [privateKey],
chainId:11155111,
allowUnlimitedContractSize: true
}
},
};
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const txnsSchema = new Schema({
hashlock: {
type: String,
required: true,
},
amountOnt: {
type: String,
required: true,
},
bidTimelock: {
type: String,
required: true
}
}, { timestamps: true });
const txns = mongoose.model('txns', txnsSchema);
module.exports = txns;
\ No newline at end of file
This diff is collapsed.
{
"name": "finalproject",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@ethersproject/providers": "^5.7.2",
"@nomicfoundation/hardhat-chai-matchers": "^1.0.6",
"@nomicfoundation/hardhat-network-helpers": "^1.0.8",
"@nomicfoundation/hardhat-toolbox": "^2.0.0",
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@nomiclabs/hardhat-etherscan": "^3.1.7",
"@typechain/ethers-v5": "^10.2.0",
"@typechain/hardhat": "^6.1.5",
"@types/chai": "^4.3.4",
"@types/mocha": "^9.1.1",
"chai": "^4.3.7",
"ethers": "^5.7.2",
"hardhat": "^2.13.1",
"hardhat-gas-reporter": "^1.0.9",
"solidity-coverage": "^0.8.2",
"ts-node": "^10.9.1",
"typechain": "^8.1.1",
"typescript": "^5.0.4"
},
"dependencies": {
"ejs": "^3.1.8",
"fs": "0.0.1-security",
"mongodb": "^4.12.0",
"mongoose": "^6.7.2",
"morgan": "^1.10.0",
"web3": "^1.8.1"
}
}
This diff is collapsed.
.netbut {
background-color: black !important;
}
.centeralign{
text-align:center;
}
.setmargin{
margin-left: 2%;
margin-right: 2%;
}
.mnbt {
display: inline;
margin: 10px 0;
padding: 10px;
width: 24%;
}
.mnbt2 {
display: inline;
margin: 10px 0;
padding: 10px;
width: 19%;
}
.mytext {
width: 300px;
}
body{
background-image: url('/background.jpg');
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
.pd{
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
const { ethers } = require("hardhat");
async function main() {
const [deployer] = await ethers.getSigners();
console.log('Deploying contracts with the account: ' + deployer.address);
// Deploy First
const EthereumContract = await ethers.getContractFactory('EthereumContract');
const first = await EthereumContract.deploy();
await first.deployed();
// Deploy Second
// const Second = await ethers.getContractFactory('SecondContract');
// const second = await Second.deploy(first.address);
console.log( "First: " + first.address );
// console.log( "Second: " + second.address );
}
main()
.then(() => process.exit())
.catch(error => {
console.error(error);
process.exit(1);
})
\ No newline at end of file
const { ethers } = require("hardhat");
async function main() {
const [deployer] = await ethers.getSigners();
console.log('Deploying contracts with the account: ' + deployer.address);
// Deploy First
const OntologyContract = await ethers.getContractFactory('OntologyContract');
const first = await OntologyContract.deploy();
await first.deployed();
// Deploy Second
// const Second = await ethers.getContractFactory('SecondContract');
// const second = await Second.deploy(first.address);
console.log( "First: " + first.address );
// console.log( "Second: " + second.address );
}
main()
.then(() => process.exit())
.catch(error => {
console.error(error);
process.exit(1);
})
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Atomic Swap</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<script src='/web3.min.js'></script>
<link rel="stylesheet" href="/style.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<h1 class="centeralign">Atomic Swap</h1>
<br >
<div class="centeralign">
<h4>Select Chain</h4>
<button type="button" class="btn btn-primary" id="ONTBut" onclick="hideElement('ETH'); showElement('ONT');">ONT</button>
<button type="button" class="btn btn-primary" id="ETHBut" onclick="hideElement('ONT'); showElement('ETH');">ETH</button>
</div>
<hr>
<div class="centeralign setmargin" id = "ONT">
<!-- ORDER STATUS -->
<div>
<label for="hashlock">Enter hash: </label>
<input type="text" name="hashlock" id="hash5">
<button onclick="printOrderListOnt(document.getElementById('hash5').value);">Get Order Details</button>
<div id="orderListOnt"></div>
<br>
<div id="bidtimer1"></div>
<br>
<div hidden id="selectedBidsDiv">
<h2>All Selected Bids Details</h2>
<table id="selectedBidsTable">
<thead>
<th>Buyer Ont Address</th>
<th>Buyer ETH Address</th>
<th>Locked Amount</th>
<th>New hashlock</th>
</thead>
</table>
</div>
<br>
</div>
<hr>
<!-- BUTTONS TO SELECT STEPS -->
<div>
<button class="mnbt" id="lt" onclick="showhide('lt');">Lock Tokens</button>
<button class="mnbt" id="co" onclick="showhide('co');">Claim ONT</button>
<button class="mnbt" id="ro" onclick="showhide('ro');">Refund ONT</button>
</div>
<hr>
<!-- LOCKING TOKENS -->
<div name="block" id="lt1">
<label for="hashlock">Enter hash: </label>
<input type="text" name="hashlock" id="hash1"><br><br>
<label for="secret3">Enter secret of the hash: </label>
<input type="text" name="secret3" id="secret3"><br><br>
<label for="amountOnt">Enter ONT tokens to exchange: </label>
<input type="text" name="amountOnt" id="amountOnt"><br><br>
<label for="hashlocks">Enter hashlocks (comma separated)</label>
<input type="text" name="hashlocks" id="hashlocks"><br><br>
<label for="buyerOntAddresses">Enter Buyer ONT Addresses (comma separated)</label>
<input type="text" name="buyerOntAddresses" id="buyerOntAddresses"><br><br>
<label for="buyerEthAddresses">Enter Buyer ETH Addresses (comma separated)</label>
<input type="text" name="buyerEthAddresses" id="buyerEthAddresses"><br><br>
<label for="amounts">Enter amount split (comma separated)</label>
<input type="text" name="amounts" id="amounts"><br><br>
<button onclick="lockAndSet(document.getElementById('hash1').value, document.getElementById('secret3').value, document.getElementById('hashlocks').value, document.getElementById('buyerOntAddresses').value, document.getElementById('buyerEthAddresses').value, document.getElementById('amounts').value, document.getElementById('amountOnt').value);">Lock and Set</button>
</div>
<!-- CLAIM ONT TOKENS BY 2ND PARTY -->
<div name="block" id="co1">
<label for="hashlock">Enter hash: </label>
<input type="text" name="hashlock" id="hash3"><br><br>
<label for="secret">Enter Secret: </label>
<input type="text" name="secret" id="secret1"><br><br>
<button onclick="claimOnt(document.getElementById('hash3').value, document.getElementById('secret1').value);">Claim ONT</button>
</div>
<!-- REFUND ONT TOKENS BY INTITIATOR -->
<div name="block" id="ro1">
<label for="hashlock">Enter hash: </label>
<input type="text" name="hashlock" id="hash4"><br><br>
<button onclick="refundOnt(document.getElementById('hash4').value);">Refund ONT</button>
</div>
<hr>
</div>
<!-- ==================================================================================================================================== -->
<div class="centeralign setmargin" id = "ETH" >
<!-- ORDER STATUS -->
<div>
<label for="hashlock">Enter hash: </label>
<input type="text" name="hashlock" id="hash6">
<button onclick="printOrderListEth(document.getElementById('hash6').value);">Get Order Details</button>
<div id="orderListEth"></div>
<br>
<div id="bidtimer2"></div>
<br>
<div hidden id="bidDetailsDiv">
<h2>All Bids Details</h2>
<table id = "bidDetailsTable">
</table>
</div>
<br>
</div>
<hr>
<!-- BUTTONS TO SELECT STEPS -->
<div>
<button class="mnbt2" id="io" onclick="showhide2('io');">Initiate Order</button>
<button class="mnbt2" id="b" onclick="showhide2('b');">Bid</button>
<button class="mnbt2" id="le" onclick="showhide2('le');">Lock ETH</button>
<button class="mnbt2" id="ce" onclick="showhide2('ce');">Claim ETH</button>
<button class="mnbt2" id="re" onclick="showhide2('re');">Refund ETH</button>
</div>
<!-- INITIATE ORDER -->
<div name="block2" id="io1">
<label for="hashlock">Enter hash: </label>
<input type="text" name="hashlock" id="hash11"><br><br>
<label for="initiatorOntAddress">Enter Initiator ONT Address: </label>
<input type="text" name="initiatorOntAddress" id="initiatorOntAddress"><br><br>
<label for="amountOnt4">Enter Amount ONT: </label>
<input type="text" name="amountOnt4" id="amountOnt4"><br><br>
<button onclick="getBidTimeLock(document.getElementById('hash11').value, document.getElementById('initiatorOntAddress').value, document.getElementById('amountOnt4').value, 'bidtimer1');">Initiate Order</button>
</div>
<!-- Sending to database will look at this later -->
<iframe name="votar" style="display:none;"></iframe>
<form id="todb" action="/txns" method="post" target="votar" style="display:none;">
<input type="hidden" name="hashlock" id="hash12"><br><br>
<!-- <input type="hidden" name="amountOnt" id="amountOnt3"><br><br>
<input type="hidden" name="bidTimelock" id="bidTimelock3"><br><br> -->
<input style="display: none;" type="submit" value="Send to Database">
</form>
<!-- BIDDING -->