import code
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/node_modules
|
||||
/build/contracts
|
||||
.env
|
||||
truffle-config.js
|
44
README.md
Normal file
@ -0,0 +1,44 @@
|
||||
# Crypto Birdies
|
||||
|
||||
This project is a clone of the famous Crypto Kitties.
|
||||
It demonstrates use of the following technologies:
|
||||
|
||||
* HTML5
|
||||
* CSS3
|
||||
* JavaScript
|
||||
* Bootstrap
|
||||
* jQuery
|
||||
* Solidity
|
||||
* web3.js
|
||||
* Truffle
|
||||
* Ganache
|
||||
* Mocha.js
|
||||
* Chai.js
|
||||
* MetaMask
|
||||
|
||||
UI Functionality:
|
||||
|
||||
* creation of bird with a 17-digit DNA sequence
|
||||
* 7 exciting animations for the birds
|
||||
* millions of color combinations for each bird
|
||||
* breeding of baby birds
|
||||
* buying and selling of birds for test ETH
|
||||
* catalog to display all birds of the user
|
||||
* market place displaying all active offers of birds both of the current user and other users
|
||||
|
||||
Technical Functionality:
|
||||
|
||||
* Creation and management of ERC721 tokens
|
||||
* Payments with ERC20 tokens (testnet)
|
||||
* Compliance with IERC721 and IERC165 (Open Zeppelin)
|
||||
* 95 unit tests for the smart contract code utilizing three additional test contracts
|
||||
* Implementation of pause functionality to allow for maintenance by the contract owner
|
||||
* Full SafeMath implementation for full protection against Over- and Underflow
|
||||
* Checks / Effects / Interactions logic to prevent re-entrency attacks
|
||||
* No external library calls to prevent Parity Freeze szenario
|
||||
* Independent Market Contract handling the trading of the NFT tokens
|
||||
* Truffle migrations
|
||||
-------------------------------------------------------------------------------------------------
|
||||
* Live demonstration: https://cryptobirdies.netlify.app
|
||||
* Birdcontract: https://ropsten.etherscan.io/address/0x70e2324ccf7a76e201dff26d4749ed1bb821c305
|
||||
* Marketcontract: https://ropsten.etherscan.io/address/0x78ad2f9c3924278692125a23ed05d4e5facfd97c
|
3719
client/assets/bootstrap/css/bootstrap-grid.css
vendored
Normal file
1
client/assets/bootstrap/css/bootstrap-grid.css.map
Normal file
7
client/assets/bootstrap/css/bootstrap-grid.min.css
vendored
Normal file
1
client/assets/bootstrap/css/bootstrap-grid.min.css.map
Normal file
331
client/assets/bootstrap/css/bootstrap-reboot.css
vendored
Normal file
@ -0,0 +1,331 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2019 The Bootstrap Authors
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
line-height: 1.15;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: #212529;
|
||||
text-align: left;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
[tabindex="-1"]:focus {
|
||||
outline: 0 !important;
|
||||
}
|
||||
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title],
|
||||
abbr[data-original-title] {
|
||||
text-decoration: underline;
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
border-bottom: 0;
|
||||
-webkit-text-decoration-skip-ink: none;
|
||||
text-decoration-skip-ink: none;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: .5rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #0056b3;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]):focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
svg {
|
||||
overflow: hidden;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
color: #6c757d;
|
||||
text-align: left;
|
||||
caption-side: bottom;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
outline: 1px dotted;
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
button,
|
||||
[type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
button:not(:disabled),
|
||||
[type="button"]:not(:disabled),
|
||||
[type="reset"]:not(:disabled),
|
||||
[type="submit"]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
input[type="radio"],
|
||||
input[type="checkbox"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input[type="date"],
|
||||
input[type="time"],
|
||||
input[type="datetime-local"],
|
||||
input[type="month"] {
|
||||
-webkit-appearance: listbox;
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: .5rem;
|
||||
font-size: 1.5rem;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type="search"] {
|
||||
outline-offset: -2px;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
1
client/assets/bootstrap/css/bootstrap-reboot.css.map
Normal file
8
client/assets/bootstrap/css/bootstrap-reboot.min.css
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2019 The Bootstrap Authors
|
||||
* Copyright 2011-2019 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
|
||||
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
|
1
client/assets/bootstrap/css/bootstrap-reboot.min.css.map
Normal file
10038
client/assets/bootstrap/css/bootstrap.css
vendored
Normal file
1
client/assets/bootstrap/css/bootstrap.css.map
Normal file
7
client/assets/bootstrap/css/bootstrap.min.css
vendored
Normal file
1
client/assets/bootstrap/css/bootstrap.min.css.map
Normal file
7013
client/assets/bootstrap/js/bootstrap.bundle.js
vendored
Normal file
1
client/assets/bootstrap/js/bootstrap.bundle.js.map
Normal file
7
client/assets/bootstrap/js/bootstrap.bundle.min.js
vendored
Normal file
1
client/assets/bootstrap/js/bootstrap.bundle.min.js.map
Normal file
4435
client/assets/bootstrap/js/bootstrap.js
vendored
Normal file
1
client/assets/bootstrap/js/bootstrap.js.map
Normal file
7
client/assets/bootstrap/js/bootstrap.min.js
vendored
Normal file
1
client/assets/bootstrap/js/bootstrap.min.js.map
Normal file
5
client/assets/bootstrap/js/popper.js
Normal file
142
client/assets/css/animations.css
Normal file
@ -0,0 +1,142 @@
|
||||
.slowRotateBird {
|
||||
animation: rotateBird 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes rotateBird {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
30% {
|
||||
transform: rotate(5deg);
|
||||
}
|
||||
60% {
|
||||
transform: rotate(-5deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
.floatingBird {
|
||||
animation: floatBird 3s ease-out infinite;
|
||||
}
|
||||
|
||||
@keyframes floatBird {
|
||||
50% {
|
||||
transform: translate(0, -20px);
|
||||
}
|
||||
}
|
||||
|
||||
.compressingBird {
|
||||
animation: compressBird 3s infinite;
|
||||
}
|
||||
|
||||
@keyframes compressBird {
|
||||
0% {
|
||||
transform: scaleY(0);
|
||||
}
|
||||
30% {
|
||||
transform: scaleY(1.3);
|
||||
}
|
||||
60% {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
100% {
|
||||
transform: scaleY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.upperSpeakingBird {
|
||||
animation: upperSpeakBird 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes upperSpeakBird {
|
||||
|
||||
50% {
|
||||
transform: rotate(-90deg) skewY(20deg) scale(1.5, 2.7);
|
||||
}
|
||||
}
|
||||
|
||||
.lowerSpeakingBird {
|
||||
animation: lowerSpeakBird 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes lowerSpeakBird {
|
||||
|
||||
50% {
|
||||
transform: rotate(135deg) skewY(20deg) scale(1.5, 1.5) translateX(-0.9em) translateY(-0.5em);
|
||||
top: 23em;
|
||||
left: 28em;
|
||||
}
|
||||
}
|
||||
|
||||
.topWaggingTail {
|
||||
animation: topWagTail 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes topWagTail {
|
||||
|
||||
50% {
|
||||
transform: rotate(60deg);
|
||||
}
|
||||
}
|
||||
|
||||
.middleWaggingTail {
|
||||
animation: middleWagTail 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes middleWagTail {
|
||||
|
||||
50% {
|
||||
transform: rotate(20deg) scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
.bottomWaggingTail {
|
||||
animation: bottomWagTail 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes bottomWagTail {
|
||||
|
||||
50% {
|
||||
transform: rotate(-50deg);
|
||||
}
|
||||
}
|
||||
|
||||
.topAttention {
|
||||
animation: tAttention 6s infinite;
|
||||
}
|
||||
|
||||
@keyframes tAttention {
|
||||
|
||||
90% {
|
||||
transform: rotate(60deg);
|
||||
}
|
||||
}
|
||||
|
||||
.bottomAttention {
|
||||
animation: bAttention 6s infinite;
|
||||
}
|
||||
|
||||
@keyframes bAttention {
|
||||
|
||||
90% {
|
||||
transform: rotate(50deg);
|
||||
}
|
||||
}
|
||||
|
||||
.evolvingHeart {
|
||||
animation: evolveHeart 6s infinite;
|
||||
}
|
||||
|
||||
@keyframes evolveHeart {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
50% {
|
||||
transform: scale(0.5);
|
||||
}
|
||||
100% {
|
||||
transform: scale(0);
|
||||
}
|
||||
}
|
240
client/assets/css/bird.css
Normal file
@ -0,0 +1,240 @@
|
||||
.bird {
|
||||
left:10em;
|
||||
font-size: 5px;
|
||||
position:relative;
|
||||
top: 15em;
|
||||
}
|
||||
|
||||
.feather_top {
|
||||
background: #ce000f;
|
||||
border: 0.8em solid black;
|
||||
border-radius: 100% 100% 100% 100% / 80% 100% 80% 100% ;
|
||||
border-right:0;
|
||||
height: 6em;
|
||||
left: 16em;
|
||||
position: absolute;
|
||||
top: -6em;
|
||||
transform: rotate(40deg);
|
||||
width: 17em;
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.feather_bottom {
|
||||
background: #ce000f;
|
||||
border: 0.8em solid black;
|
||||
border-radius: 100% 100% 100% 100% / 80% 90% 50% 100% ;
|
||||
border-right: 0;
|
||||
height: 5em;
|
||||
left: 8em;
|
||||
position: absolute;
|
||||
top: -4em;
|
||||
transform: rotate(10deg);
|
||||
width: 15em;
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.bird_body {
|
||||
border: 1em solid black;
|
||||
border-radius: 100% / 120% 100% 95% 85%;
|
||||
height: 42em;
|
||||
position:absolute;
|
||||
width: 45em;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.bird_body_inner {
|
||||
background: #ce000f;
|
||||
border: none;
|
||||
height: 40.2em;
|
||||
position:absolute;
|
||||
width: 43em;
|
||||
z-index: 3
|
||||
}
|
||||
|
||||
.deco_1 {
|
||||
background: #ab060c;
|
||||
border: none;
|
||||
border-radius: 100% / 120% 100% 95% 85%;
|
||||
top: 24em;
|
||||
height: 4.5em;
|
||||
left: 7em;
|
||||
position: absolute;
|
||||
transform: rotate(-25deg);
|
||||
width: 4em;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.deco_2 {
|
||||
background: #ab060c;
|
||||
border: none;
|
||||
border-radius: 100% / 120% 100% 95% 85%;
|
||||
top: 20em;
|
||||
height: 7.5em;
|
||||
left: 12em;
|
||||
position: absolute;
|
||||
transform: rotate(-15deg);
|
||||
width: 4em;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.deco_3 {
|
||||
background: #ab060c;
|
||||
border: none;
|
||||
border-radius: 100% / 120% 100% 95% 85%;
|
||||
top: 19em;
|
||||
height: 9em;
|
||||
left: 17em;
|
||||
position: absolute;
|
||||
transform: rotate(-10deg);
|
||||
width: 10em;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.deco_4 {
|
||||
background: #ab060c;
|
||||
border: none;
|
||||
border-radius: 100% / 120% 100% 95% 85%;
|
||||
top: 17.5em;
|
||||
height: 9em;
|
||||
left: 31em;
|
||||
position: absolute;
|
||||
transform: rotate(-10deg);
|
||||
width: 10em;
|
||||
z-index: 40;
|
||||
}
|
||||
|
||||
.belly {
|
||||
border: #E5E8D5 solid;
|
||||
border-bottom-width: 0;
|
||||
border-left-width: 14em;
|
||||
border-radius: 100% 100% 100% 100% / 120% 120% 80% 80%;
|
||||
border-right-width: 14em;
|
||||
border-top-width: 12em;
|
||||
left: 8.5em;
|
||||
position: absolute;
|
||||
top: 29em;
|
||||
z-index: 5
|
||||
}
|
||||
|
||||
.face {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.eye {
|
||||
background: #dddddd;
|
||||
border: 0.9em black solid;
|
||||
border-radius: 100%;
|
||||
height: 10.7em;
|
||||
position: absolute;
|
||||
width: 10.7em;
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.pupil {
|
||||
background: black;
|
||||
border-radius: 100%;
|
||||
height: 3em;
|
||||
position: relative;
|
||||
width: 3em;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.eye_right {
|
||||
left: 30em;
|
||||
top: 16em;
|
||||
}
|
||||
|
||||
.eye_left {
|
||||
left: 20em;
|
||||
top: 16em;
|
||||
}
|
||||
|
||||
.eye_right .pupil {
|
||||
left: 1.5em;
|
||||
top: 3em;
|
||||
}
|
||||
|
||||
.eye_left .pupil {
|
||||
left: 5em;
|
||||
top: 3em;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
background: black;
|
||||
height: 3.2em;
|
||||
position: absolute;
|
||||
width: 13em;
|
||||
z-index: 7;
|
||||
}
|
||||
|
||||
.eye_right .eyebrow {
|
||||
left: -1em;
|
||||
top: -1.5em;
|
||||
transform: rotate(-11deg);
|
||||
}
|
||||
|
||||
.eye_left .eyebrow {
|
||||
left: -3em;
|
||||
top: -1.5em;
|
||||
transform: rotate(11deg);
|
||||
}
|
||||
|
||||
.beak_upper {
|
||||
background: #e9b90d;
|
||||
border: 0.3em solid black;
|
||||
border-bottom-left-radius: 200%;
|
||||
border-top-left-radius: 10%;
|
||||
border-top-right-radius: 40%;
|
||||
height: 5em;
|
||||
left: 31em;
|
||||
position: relative;
|
||||
top: 26em;
|
||||
transform: rotate(-70deg) skewY(20deg) scale(1.5, 2.7);
|
||||
width: 5em;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.beak_lower {
|
||||
background: #e28810;
|
||||
border: 0.3em solid black;
|
||||
border-bottom-left-radius: 200%;
|
||||
border-top-left-radius: 10%;
|
||||
border-top-right-radius: 30%;
|
||||
height: 7.5em;
|
||||
left: 30em;
|
||||
position: relative;
|
||||
top: 20em;
|
||||
transform: rotate(120deg) skewY(20deg) scale(1.5, 1.5);
|
||||
width: 6em;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.tail_top {
|
||||
border-color: transparent transparent transparent black;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
border-width: 2em 0em 2em 10em;
|
||||
left: -5em;
|
||||
top: 16.5em;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.tail_middle {
|
||||
border-color: transparent transparent transparent black;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
border-width: 3em 0em 2em 15em;
|
||||
left: -8em;
|
||||
top: 18em;
|
||||
transform: rotate(12deg);
|
||||
}
|
||||
|
||||
.tail_bottom {
|
||||
border-color: transparent transparent transparent black;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
border-width: 2em 0em 1em 7em;
|
||||
left: -4em;
|
||||
top: 21.2em;
|
||||
transform: rotate(-35deg);
|
||||
}
|
306
client/assets/css/styles.css
Normal file
@ -0,0 +1,306 @@
|
||||
/* HTML Elements */
|
||||
body {
|
||||
background:
|
||||
url(../images/vector-river-scene-with-trees-and-hills.jpg);
|
||||
background-size: cover;
|
||||
font-family: Poppins;
|
||||
font-weight: 500;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
footer {
|
||||
background: whitesmoke;
|
||||
border-radius: 5px;
|
||||
height: 30px;
|
||||
padding: 2vh;
|
||||
padding-bottom: 40px;
|
||||
text-align: center;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #f8f9fa;
|
||||
}
|
||||
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
color: rgb(48, 46, 46);overflow-y: scroll;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #f8f9fa;
|
||||
height: 0.8em;
|
||||
}
|
||||
|
||||
/* Classes */
|
||||
.birdAttributes {
|
||||
background-color: #ededed;
|
||||
border-radius: 10px;
|
||||
left: 3em;
|
||||
padding: 25px;
|
||||
}
|
||||
|
||||
.birdBox {
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.bottomList {
|
||||
margin-left: -2.5em;
|
||||
}
|
||||
|
||||
.buyBox {
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 10px;
|
||||
display: inline-flex;
|
||||
height: 34em;
|
||||
min-width: 20.7em;
|
||||
max-width: 20.7em;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.buyButton {
|
||||
border-radius: 5px;
|
||||
margin-left: 7em;
|
||||
}
|
||||
|
||||
.cancelButton {
|
||||
border-radius: 5px;
|
||||
margin-left: 5em;
|
||||
}
|
||||
|
||||
.card-deck{
|
||||
background: transparent;
|
||||
border-width: 5px;
|
||||
position: relative;
|
||||
top: 0em;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.card-img-top {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.card-special {
|
||||
background-color: seagreen;
|
||||
height: 10em;
|
||||
}
|
||||
|
||||
.card-text {
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.catalogBox {
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 10px;
|
||||
height: 34em;
|
||||
min-width: 20.7em;
|
||||
max-width: 20.7em;
|
||||
padding-right: 30px;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.dnaDiv {
|
||||
bottom: 5px;
|
||||
font-size: 18px;
|
||||
left:20px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.evolvingHeart {
|
||||
left: -20em;
|
||||
position: relative;
|
||||
top: -20em;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
border-radius: 5px;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.offerBox {
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 10px;
|
||||
display: inline-flex;
|
||||
height: 34em;
|
||||
min-width: 20.7em;
|
||||
max-width: 20.7em;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-left: -0.4em;
|
||||
}
|
||||
|
||||
.submitButton {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.topCard {
|
||||
background: seagreen;
|
||||
border-width: 5px;
|
||||
float: none;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* IDs */
|
||||
#breedAgainButton {
|
||||
left: 28.4em;
|
||||
position: relative;
|
||||
top: -65em;
|
||||
}
|
||||
|
||||
#breedButton {
|
||||
left: 10em;
|
||||
position: relative;
|
||||
top: -50em;
|
||||
}
|
||||
|
||||
#breedFooter {
|
||||
position: relative;
|
||||
top: -33em;
|
||||
}
|
||||
|
||||
#cardButton {
|
||||
left: 2em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#cardTitle {
|
||||
color: #343a40;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#childBox {
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 10px;
|
||||
height: 31em;
|
||||
min-width: 21em;
|
||||
max-width: 21em;
|
||||
padding-right: 30px;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
#childDisplay {
|
||||
left: 21.3em;
|
||||
opacity: 90%;
|
||||
position: relative;
|
||||
top: -66em;
|
||||
width: 30em;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
#createButton {
|
||||
border-radius: 5px;
|
||||
left: 21em;
|
||||
}
|
||||
|
||||
#dadData {
|
||||
float: right;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
#dameBox {
|
||||
background-color: #fdb1f3;
|
||||
border-radius: 10px;
|
||||
height: 31em;
|
||||
min-width: 21em;
|
||||
max-width: 21em;
|
||||
padding-right: 30px;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
#dameButton {
|
||||
left: 8em;
|
||||
position: relative;
|
||||
top: -34em;
|
||||
}
|
||||
|
||||
#dameDisplay {
|
||||
left: 1em;
|
||||
opacity: 90%;
|
||||
position: relative;
|
||||
top: -3em;
|
||||
width: 30em;
|
||||
}
|
||||
|
||||
#defaultButton {
|
||||
border-radius: 5px;
|
||||
left: 3.4em;
|
||||
}
|
||||
|
||||
#genData {
|
||||
float: right;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
#idData {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#logo {
|
||||
border-radius: 40%;
|
||||
}
|
||||
|
||||
#mumData {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#offerAmount {
|
||||
position: relative;
|
||||
width: min-content;
|
||||
}
|
||||
|
||||
#pauseMessage {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#randomizeButton {
|
||||
border-radius: 5px;
|
||||
left: 0.2em;
|
||||
}
|
||||
|
||||
#sireBox {
|
||||
background-color: #5caaf8;
|
||||
border-radius: 10px;
|
||||
height: 31em;
|
||||
min-width: 21em;
|
||||
max-width: 21em;
|
||||
padding-right: 30px;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
#sireButton {
|
||||
left: 40em;
|
||||
position: relative;
|
||||
top: -34em;
|
||||
}
|
||||
|
||||
#sireDisplay {
|
||||
left: 41.5em;
|
||||
opacity: 90%;
|
||||
position: relative;
|
||||
top: -34.5em;
|
||||
width: 30em;
|
||||
}
|
||||
|
||||
#swapButton {
|
||||
left: 26.4em;
|
||||
position: relative;
|
||||
top: -49em;
|
||||
}
|
BIN
client/assets/images/vector-river-scene-with-trees-and-hills.jpg
Normal file
After Width: | Height: | Size: 884 KiB |
BIN
client/assets/js/.DS_Store
vendored
Normal file
875
client/assets/js/abi.js
Normal file
@ -0,0 +1,875 @@
|
||||
var abi = {
|
||||
birdContract: [
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "symbol",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "approved",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "operator",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bool",
|
||||
"name": "approved",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "ApprovalForAll",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "birdId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "mumId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "dadId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "genes",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Birth",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approvalOneBird",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "birdOwner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "close",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "gen0Counter",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "maxGen0Birds",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getContractOwner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "contractowner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_dadId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_mumId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "breed",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes4",
|
||||
"name": "_interfaceId",
|
||||
"type": "bytes4"
|
||||
}
|
||||
],
|
||||
"name": "supportsInterface",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "genes",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "createBirdGen0",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getBird",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "genes",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "birthTime",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "mumId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "dadId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "generation",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getAllBirdsOfOwner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "total",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "tokenName",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "tokenSymbol",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ownerOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_approved",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_operator",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "_approved",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "setApprovalForAll",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getApproved",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_operator",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isApprovedForAll",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "safeTransferFrom",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "safeTransferFrom",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
],
|
||||
marketContract: [
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_contractAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "TxType",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "MarketTransaction",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "message",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "recipient",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "MonetaryTransaction",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_contractAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setContract",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "pause",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "resume",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "isPaused",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getOffer",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "seller",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "price",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "index",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "tokenId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "active",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getAllTokensOnSale",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "listOfOffers",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_price",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setOffer",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "removeOffer",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "buyBird",
|
||||
"outputs": [],
|
||||
"payable": true,
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getBalance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "withdrawFunds",
|
||||
"outputs": [],
|
||||
"payable": true,
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
}
|
369
client/assets/js/blockchain.js
Normal file
@ -0,0 +1,369 @@
|
||||
// var web3 = new Web3(Web3.givenProvider);//Wallet will inject the selected network
|
||||
var web3 = new Web3('ws://192.168.100.22:8545')
|
||||
// var web3 = new Web3('ws://localhost:7545')
|
||||
ethereum.autoRefreshOnNetworkChange = false;
|
||||
|
||||
var birdInstance;
|
||||
var marketInstance;
|
||||
var user;
|
||||
var access = false;
|
||||
// localhost
|
||||
// var birdAddress = "0xfB0fA5Ae35E9A2d079EDd2Eb9D627aa2f61E81CE";
|
||||
// var marketAddress = "0x827953AE5656E0f922fa898f57B2eE600BFE4b8F"
|
||||
// 192.168.100.22
|
||||
var birdAddress = "0xCfEB869F69431e42cdB54A4F4f105C19C080A601";
|
||||
var marketAddress = "0xC89Ce4735882C9F0f0FE26686c53074E09B0D550"
|
||||
// var birdAddress = "0x70e2324ccf7a76e201dff26d4749ed1bb821c305"; //Ropsten: 0x70e2324ccf7a76e201dff26d4749ed1bb821c305
|
||||
// var marketAddress = "0x78ad2f9c3924278692125a23ed05d4e5facfd97c"; // Ropsten: 0x78ad2f9c3924278692125a23ed05d4e5facfd97c
|
||||
|
||||
async function connectWallet() {
|
||||
return window.ethereum.enable().then(function(accounts){
|
||||
user = accounts[0];
|
||||
birdInstance = new web3.eth.Contract(abi.birdContract, birdAddress, {from: user});
|
||||
marketInstance = new web3.eth.Contract(abi.marketContract, marketAddress, {from: user});
|
||||
|
||||
birdInstance.events.Birth()
|
||||
.on('data', async function (event) {
|
||||
let owner = event.returnValues.owner;
|
||||
let birdId = event.returnValues.birdId;
|
||||
let mumId = event.returnValues.mumId;
|
||||
let dadId = event.returnValues.dadId;
|
||||
let genes = event.returnValues.genes;
|
||||
|
||||
//check if the event belongs to one of the currently connected addresses
|
||||
access = await isCurrentUserOwner(owner);
|
||||
|
||||
//birth events
|
||||
if (location.href.includes("breeding") && (access)) {
|
||||
$('#birdCreation').text(
|
||||
"A new bird is born! Your baby bird will appear in the catalog after confirmation from the blockchain. Owner: "
|
||||
+ owner
|
||||
+ " | BirdID: " + birdId
|
||||
+ " | MumID: " + mumId
|
||||
+ " | DadID: " + dadId
|
||||
+ " | Genes: " + genes);
|
||||
await renderChild(birdId);
|
||||
$('#breedAgainButton').css("display", "block");
|
||||
$('#breedFooter').css("top", "-65.5em");
|
||||
$('#breedAgainButton').on("click", () => {
|
||||
location.reload();
|
||||
});
|
||||
} else if (location.href.includes("studio") && (access)) {
|
||||
$('#birdCreation').css("display", "block");
|
||||
$('#birdCreation').text(
|
||||
"Bird successfully created! After confirmation from the blockchain, your new bird will appear in the catalog. Owner: "
|
||||
+ owner
|
||||
+ " | BirdID: " + birdId
|
||||
+ " | MumID: " + mumId
|
||||
+ " | DadID: " + dadId
|
||||
+ " | Genes: " + genes);
|
||||
};
|
||||
})
|
||||
.on('error', console.error);
|
||||
|
||||
marketInstance.events.MarketTransaction()
|
||||
.on('data', async function (event) {
|
||||
let eventType = event.returnValues.TxType;
|
||||
let owner = event.returnValues.owner;
|
||||
let tokenId = event.returnValues.tokenId;
|
||||
|
||||
//check if the event belongs to one of the currently connected addresses
|
||||
access = await isCurrentUserOwner(owner);
|
||||
|
||||
//events
|
||||
if ((eventType == "Offer created") && (access)) {
|
||||
$('#offerCreated').css("display", "block");
|
||||
$('#offerCreated').text(
|
||||
"Offer successfully created! After confirmation from the blockchain, your new offer will appear in the market place. Owner: "
|
||||
+ owner + " | BirdID: " + tokenId);
|
||||
};
|
||||
if ((eventType == "Offer removed") && (access)) {
|
||||
$('#offerRemoved').css("display", "block");
|
||||
$('#offerRemoved').text(
|
||||
"Offer successfully removed! After confirmation from the blockchain, your bird will again appear in the catalog. Owner: "
|
||||
+ user + " | BirdID: " + tokenId);
|
||||
};
|
||||
if ((eventType == "Bird successfully purchased") && (access)) {
|
||||
$('#birdPurchased').css("display", "block");
|
||||
$('#birdPurchased').text(
|
||||
"Bird successfully purchased! After confirmation from the blockchain, your new bird will appear in the catalog. Owner: "
|
||||
+ user + " | BirdID: " + tokenId);
|
||||
};
|
||||
})
|
||||
.on('error', console.error);
|
||||
});
|
||||
};
|
||||
|
||||
async function isCurrentUserOwner(eventOwner) {
|
||||
var currentUsers = await web3.eth.getAccounts();
|
||||
for (let i = 0; i < currentUsers.length; i++) {
|
||||
if (currentUsers[i] == eventOwner) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
async function checkPause() {
|
||||
return await marketInstance.methods.isPaused().call();
|
||||
};
|
||||
|
||||
async function pauseResumeContract() {
|
||||
$('#pauseMessage').show();
|
||||
$('#pauseMessage').text("Waiting for confirmations from blockchain...");
|
||||
if(!await checkPause()){
|
||||
await marketInstance.methods.pause().send({}, function(error){
|
||||
if (error) {
|
||||
console.log(error);
|
||||
}});
|
||||
} else {
|
||||
await marketInstance.methods.resume().send({}, function(error){
|
||||
if (error) {
|
||||
console.log(error);
|
||||
};
|
||||
});
|
||||
};
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
async function initializeMarketplace() {
|
||||
var marketplaceApprovedOperator = await birdInstance.methods.isApprovedForAll(
|
||||
user, marketAddress).call();
|
||||
if (marketplaceApprovedOperator == false) {
|
||||
await birdInstance.methods.setApprovalForAll(marketAddress, true).send(
|
||||
{gas: 1000000}, function(error){
|
||||
if (error) {
|
||||
console.log(error);
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
async function onlyOwnerAccess() {//limits access to studio and pause/resume to contract owner
|
||||
var owner = await birdInstance.methods.getContractOwner().call();
|
||||
owner = owner.toLowerCase()
|
||||
if (user == owner) {
|
||||
$('#designStudio').show();
|
||||
if(await checkPause()) {
|
||||
$('#pauseButton').text('Resume Contract');
|
||||
$('#pauseButton').show();
|
||||
} else {
|
||||
$('#pauseButton').text('Pause Contract');
|
||||
$('#pauseButton').show();
|
||||
};
|
||||
$('#pauseButton').show();
|
||||
|
||||
//logic for other users
|
||||
} else {
|
||||
$('#designStudio').hide();
|
||||
$('#pauseButton').hide();
|
||||
if (location.href.replace(location.origin,'') == "/client/studio.html") {
|
||||
window.location.href = "./index.html";
|
||||
};
|
||||
};
|
||||
// var currentUser = await web3.eth.getAccounts();
|
||||
|
||||
// for (let i = 0; i < currentUser.length; i++) {
|
||||
|
||||
// //logic for owner
|
||||
// if (currentUser[i] == owner) {
|
||||
// $('#designStudio').show();
|
||||
// if(await checkPause()) {
|
||||
// $('#pauseButton').text('Resume Contract');
|
||||
// $('#pauseButton').show();
|
||||
// } else {
|
||||
// $('#pauseButton').text('Pause Contract');
|
||||
// $('#pauseButton').show();
|
||||
// };
|
||||
// $('#pauseButton').show();
|
||||
|
||||
// //logic for other users
|
||||
// } else {
|
||||
// $('#designStudio').hide();
|
||||
// $('#pauseButton').hide();
|
||||
// if (location.href.replace(location.origin,'') == "/client/studio.html") {
|
||||
// window.location.href = "./index.html";
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
|
||||
//Pause message applies to all users
|
||||
if(await checkPause()) {
|
||||
$('#pauseMessage').show();
|
||||
$('#withdrawBox').hide();
|
||||
} else {
|
||||
$('#pauseMessage').hide();
|
||||
$('#withdrawBox').show();
|
||||
};
|
||||
|
||||
//event listener for pause button
|
||||
$('#pauseButton').click(async ()=>{
|
||||
if(await checkPause()) {
|
||||
alert('Are you sure you want to RESUME withdrawFunds() and buyBird() for all users?');
|
||||
} else {
|
||||
alert('Are you sure you want to PAUSE withdrawFunds() and buyBird() for all users?');
|
||||
};
|
||||
await pauseResumeContract();
|
||||
});
|
||||
};
|
||||
|
||||
async function withdraw() {
|
||||
await marketInstance.methods.withdrawFunds().send({}, function(error){
|
||||
if (error) {
|
||||
$('#withdrawButton').show();
|
||||
console.log(error);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
async function returnBalance() {
|
||||
var balance;
|
||||
try {
|
||||
balance = await marketInstance.methods.getBalance().call();
|
||||
if (balance >= 0) {
|
||||
return web3.utils.fromWei(balance);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return;
|
||||
};
|
||||
};
|
||||
|
||||
async function sellBird(price, id) {
|
||||
$('#offerCreated').css("display", "block");
|
||||
$('#offerCreated').text("Waiting for confirmations from blockchain...");
|
||||
var inWei = web3.utils.toWei(price, "ether");
|
||||
await marketInstance.methods.setOffer(inWei, id).send({gas: 1000000}, function(error){
|
||||
if (error) {
|
||||
$(`#birdPrice${id}`).show();
|
||||
$(`#offerButton${id}`).show();
|
||||
console.log(error);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
async function removeOffer(id) {
|
||||
$('#offerRemoved').css("display", "block");
|
||||
$('#offerRemoved').text("Waiting for confirmations from blockchain...");
|
||||
await marketInstance.methods.removeOffer(id).send({}, function(error){
|
||||
if (error) {
|
||||
$(`#cancelButton${id}`).show();
|
||||
console.log(error);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
async function buyBird(price, id) {
|
||||
$('#birdPurchased').css("display", "block");
|
||||
$('#birdPurchased').text("Waiting for confirmations from blockchain...");
|
||||
var inWei = web3.utils.toWei(price, "ether");
|
||||
await marketInstance.methods.buyBird(id).send({ value: inWei, gas: 1000000 }, function(error){
|
||||
if (error) {
|
||||
$(`#buyButton${id}`).show();
|
||||
console.log(error);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
async function getPrice(id) {
|
||||
var result;
|
||||
try {
|
||||
result = await marketInstance.methods.getOffer(id).call();
|
||||
if (result.price > 0 && result.active == true) {
|
||||
ethPrice = web3.utils.fromWei(result.price, "ether");
|
||||
return ethPrice;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return;
|
||||
};
|
||||
};
|
||||
|
||||
async function createBird() {
|
||||
await birdInstance.methods.createBirdGen0(getDna()).send({gas: 1000000}, function(error){
|
||||
if (error) {
|
||||
console.log(error);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
async function getBirdsOfOwner() {
|
||||
var ids = [];
|
||||
try {
|
||||
ids = await birdInstance.methods.getAllBirdsOfOwner(user).call();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
};
|
||||
return ids;
|
||||
};
|
||||
|
||||
async function getBirdsOnSale() {
|
||||
var ids = [];
|
||||
try {
|
||||
ids = await marketInstance.methods.getAllTokensOnSale().call();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
};
|
||||
return ids;
|
||||
};
|
||||
|
||||
async function buildCatalog(ids){
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
bird = await birdInstance.methods.getBird(ids[i]).call();
|
||||
appendBirdToCatalog(bird, ids[i]);
|
||||
};
|
||||
activateCatalogEventListeners();//must be activated after all buttons are rendered.
|
||||
};
|
||||
|
||||
async function buildModal(ids){
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
bird = await birdInstance.methods.getBird(ids[i]).call();
|
||||
appendBirdToModal(bird, ids[i]);
|
||||
};
|
||||
};
|
||||
|
||||
async function buildMarket(ids){
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
bird = await birdInstance.methods.getBird(ids[i]).call();
|
||||
await appendBirdToMarket(bird, ids[i]);
|
||||
};
|
||||
await activateBuyButtonListeners();//must be activated after all buttons are rendered.
|
||||
};
|
||||
|
||||
async function buildOffers(ids){
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
bird = await birdInstance.methods.getBird(ids[i]).call();
|
||||
await appendBirdToOffers(bird, ids[i]);
|
||||
};
|
||||
activateCancelButtonListeners();
|
||||
};
|
||||
|
||||
async function getBirdDna(id) {
|
||||
return await birdInstance.methods.getBird(id).call();
|
||||
};
|
||||
|
||||
async function breedBird(dadId, mumId) {
|
||||
$('#birdCreation').show();
|
||||
$('#birdCreation').text("Waiting for confirmations from blockchain...");
|
||||
$('.evolvingHeart').show();
|
||||
$('#breedButton').hide();
|
||||
$('#dameButton').hide();
|
||||
$('#sireButton').hide();
|
||||
$('#swapButton').hide();
|
||||
$('#breedFooter').css("top", "-99em");
|
||||
await birdInstance.methods.breed(dadId, mumId).send({gas: 1000000}, function(error){
|
||||
if (error) {
|
||||
$('#birdCreation').hide();
|
||||
$('.evolvingHeart').hide();
|
||||
$('#breedButton').show();
|
||||
$('#dameButton').show();
|
||||
$('#sireButton').show();
|
||||
$('#breedFooter').css("top", "-33em");
|
||||
if(ids.length == 2) {
|
||||
$('#swapButton').show();
|
||||
};
|
||||
console.log(error);
|
||||
};
|
||||
});
|
||||
};
|
451
client/assets/js/breeding.js
Normal file
@ -0,0 +1,451 @@
|
||||
var dameId;
|
||||
var sireId;
|
||||
var ids;
|
||||
|
||||
$(document).ready(async () => { //when page is loaded, get latest instance of blockchain
|
||||
$('#breedAgainButton').css("display", "none");
|
||||
await connectWallet(); //connect MetaMask (if not already connected)
|
||||
await onlyOwnerAccess();
|
||||
ids = await getBirdsOfOwner(); //fill array with ids for all birds of this address
|
||||
dameId = ids[0];
|
||||
sireId = ids[1];
|
||||
if (ids.length == 2) { //user must own at least two birds to continue
|
||||
await renderDameAndSire(dameId, sireId);
|
||||
$('#insufficient').hide();
|
||||
$('#swapButton').css("display", "block");
|
||||
$('#swapButton').click(async function() { //swap dame and sire if only 2 birds in array
|
||||
var helper = dameId;
|
||||
dameId = sireId;
|
||||
sireId = helper;
|
||||
await renderDameAndSire(dameId, sireId);
|
||||
})
|
||||
} else if (ids.length > 2) {
|
||||
$('#insufficient').hide();
|
||||
$('#swapButton').css("display", "none");
|
||||
await buildModal(ids); //iterates through array and returns full info from blockchain
|
||||
await renderDameAndSire(ids[0], ids[1]);
|
||||
};
|
||||
activateMouseListeners();
|
||||
});
|
||||
|
||||
function appendBirdToModal(dna, id) {
|
||||
modalBox(id);
|
||||
renderBird(`#BirdBox${id}`, birdDna(dna), id);
|
||||
};
|
||||
|
||||
async function setUpModal() {
|
||||
$('.row').empty(); //clear modal content
|
||||
ids = await getBirdsOfOwner(); //get a fresh array from the blockcahin
|
||||
ids = [...ids]
|
||||
var index = ids.findIndex(bird => bird == dameId); //search for dame
|
||||
if (index >= 0) { //make sure element is in array
|
||||
ids.splice(index, 1); //remove current dame from array
|
||||
};
|
||||
index = ids.findIndex(bird => bird == sireId);
|
||||
if (index >= 0) { //make sure element is in array
|
||||
ids.splice(index, 1); //remove current sire from array
|
||||
};
|
||||
await buildModal(ids); //iterates through array and returns full info from blockchain
|
||||
$('#birdSelection').modal('show'); //open modal
|
||||
activateMouseListeners();
|
||||
};
|
||||
|
||||
async function renderDameAndSire(dameId, sireId) {
|
||||
dameBox(dameId);
|
||||
var dna = await getBirdDna(dameId);//returns bird instance from blockchain
|
||||
var obj = birdDna(dna, dameId);//creates dna object for rendering
|
||||
renderBird(`#dameBox`, obj, dameId);//renders bird
|
||||
sireBox(sireId);
|
||||
dna = await getBirdDna(sireId)
|
||||
obj = birdDna(dna, sireId);
|
||||
renderBird(`#sireBox`, obj, sireId);
|
||||
};
|
||||
|
||||
async function renderChild(id) {
|
||||
childBox(id);
|
||||
var dna = await getBirdDna(id);
|
||||
var obj = birdDna(dna, id);
|
||||
renderBird(`#childBox`, obj, id);
|
||||
};
|
||||
|
||||
//Listeners for buttons
|
||||
$('#dameButton').on("click", async () => {
|
||||
await setUpModal();
|
||||
selectDame(); //functionality when dame is to be selected
|
||||
});
|
||||
|
||||
$('#sireButton').on("click", async () => {
|
||||
await setUpModal();
|
||||
selectSire();//modal functionality when sire is to be selected
|
||||
});
|
||||
|
||||
$('#breedButton').on("click", async () => { //sends parent IDs to blockchain with request to breed child
|
||||
await breedBird(sireId, dameId);
|
||||
});
|
||||
|
||||
//Listeners for selections
|
||||
function selectDame(){
|
||||
$(`[id^='BirdBox']`).off("click");
|
||||
$(`[id^='BirdBox']`).on("click", async function() { //arrow function ES6 doesn't work with $(this)
|
||||
dameId = $(this).attr("id").substring(7); //works after removing arrow function.
|
||||
dameBox(dameId);//render box
|
||||
var dna = await getBirdDna(dameId)
|
||||
var obj = birdDna(dna, dameId);
|
||||
renderBird(`#dameBox`, obj, dameId);//render bird
|
||||
$('#birdSelection').modal('toggle'); //close modal
|
||||
});
|
||||
};
|
||||
|
||||
function selectSire(){
|
||||
$(`[id^='BirdBox']`).off("click");
|
||||
$(`[id^='BirdBox']`).on("click", async function() { //arrow function ES6 doesn't work with $(this)
|
||||
sireId = $(this).attr("id").substring(7); //works after removing arrow function.
|
||||
sireBox(sireId);//render box
|
||||
var dna = await getBirdDna(sireId)
|
||||
var obj = birdDna(dna, sireId);
|
||||
renderBird(`#sireBox`, obj, sireId);//render bird
|
||||
$('#birdSelection').modal('toggle'); //close modal
|
||||
});
|
||||
};
|
||||
|
||||
//Listener for eye animation
|
||||
function activateMouseListeners() {
|
||||
$('.CatalogBox').on("mousemove", () => {
|
||||
var eyeballs = $('.eyesFollow');
|
||||
document.onmousemove = function(event) {
|
||||
var x = event.clientX * 65 / window.innerWidth + "%";
|
||||
var y = event.clientY * 65 / window.innerHeight + "%";
|
||||
for (let i = 0; i < eyeballs.length; i++) {
|
||||
eyeballs[i].style.left = x;
|
||||
eyeballs[i].style.top = y;
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
//dynamic elements for breeding page
|
||||
function dameBox(id) {
|
||||
var boxDiv = `<div id="dameBox" class="col-lg-6 CatalogBox m-2 light-b-shadow">
|
||||
<div class="bird">
|
||||
<div class="tail">
|
||||
<div class="tail_top"></div>
|
||||
<div class="tail_middle"></div>
|
||||
<div class="tail_bottom"></div>
|
||||
</div>
|
||||
<div class="feather">
|
||||
<div class="feather_top"></div>
|
||||
<div class="feather_bottom"></div>
|
||||
</div>
|
||||
<div class="bird_body">
|
||||
<div class="bird_body bird_body_inner"></div>
|
||||
<div class="deco_1"></div>
|
||||
<div class="deco_2"></div>
|
||||
<div class="deco_3"></div>
|
||||
<div class="deco_4"></div>
|
||||
</div>
|
||||
<div class="belly"></div>
|
||||
<div class="face">
|
||||
<div class="eye eye_right">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="eye eye_left">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="beak">
|
||||
<div class="beak_upper"></div>
|
||||
<div class="beak_lower"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<div class="dnaDiv">
|
||||
<b>
|
||||
<div id="idData">
|
||||
ID:
|
||||
<span>` + id + `</span>
|
||||
</div>
|
||||
<div id="genData">
|
||||
GEN:
|
||||
<span id="generation` + id + `"></span>
|
||||
</div><br>
|
||||
<div id="mumData">
|
||||
MUM:
|
||||
<span id="mum` + id + `"></span>
|
||||
</div>
|
||||
<div id="dadData">
|
||||
DAD:
|
||||
<span align="right" id="dad` + id + `"></span><br>
|
||||
</div><br>
|
||||
DNA:
|
||||
<span id="dnaTopFeather` + id + `"></span>
|
||||
<span id="dnaBodyFeather` + id + `"></span>
|
||||
<span id="dnaTopBeak` + id + `"></span>
|
||||
<span id="dnaBottomBeak` + id + `"></span>
|
||||
<span id="dnaEyesShape` + id + `"></span>
|
||||
<span id="dnaDecorationPattern` + id + `"></span>
|
||||
<span id="dnaDecorationAtEye` + id + `"></span>
|
||||
<span id="dnaDecorationMid` + id + `"></span>
|
||||
<span id="dnaDecorationSmall` + id + `"></span>
|
||||
<span id="dnaAnimation` + id + `"></span><br>
|
||||
<ul class="ml-4">
|
||||
<li class="bottomList"><span id="bottomeyetext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomdecorationpatterntext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomanimationtext`
|
||||
+ id + `"></span></li>
|
||||
</ul>
|
||||
<div align="center">DAME</div>
|
||||
</b>
|
||||
</div>
|
||||
</div>`
|
||||
$('#dameDisplay').empty();
|
||||
$('#dameDisplay').append(boxDiv);
|
||||
};
|
||||
|
||||
function sireBox(id) {
|
||||
var boxDiv = `<div id="sireBox" class="col-lg-4 CatalogBox m-2 light-b-shadow">
|
||||
<div class="bird">
|
||||
<div class="tail">
|
||||
<div class="tail_top"></div>
|
||||
<div class="tail_middle"></div>
|
||||
<div class="tail_bottom"></div>
|
||||
</div>
|
||||
<div class="feather">
|
||||
<div class="feather_top"></div>
|
||||
<div class="feather_bottom"></div>
|
||||
</div>
|
||||
<div class="bird_body">
|
||||
<div class="bird_body bird_body_inner"></div>
|
||||
<div class="deco_1"></div>
|
||||
<div class="deco_2"></div>
|
||||
<div class="deco_3"></div>
|
||||
<div class="deco_4"></div>
|
||||
</div>
|
||||
<div class="belly"></div>
|
||||
<div class="face">
|
||||
<div class="eye eye_right">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="eye eye_left">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="beak">
|
||||
<div class="beak_upper"></div>
|
||||
<div class="beak_lower"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<div class="dnaDiv">
|
||||
<b>
|
||||
<div id="idData">
|
||||
ID:
|
||||
<span>` + id + `</span>
|
||||
</div>
|
||||
<div id="genData">
|
||||
GEN:
|
||||
<span id="generation` + id + `"></span>
|
||||
</div><br>
|
||||
<div id="mumData">
|
||||
MUM:
|
||||
<span id="mum` + id + `"></span>
|
||||
</div>
|
||||
<div id="dadData">
|
||||
DAD:
|
||||
<span align="right" id="dad` + id + `"></span><br>
|
||||
</div><br>
|
||||
DNA:
|
||||
<span id="dnaTopFeather` + id + `"></span>
|
||||
<span id="dnaBodyFeather` + id + `"></span>
|
||||
<span id="dnaTopBeak` + id + `"></span>
|
||||
<span id="dnaBottomBeak` + id + `"></span>
|
||||
<span id="dnaEyesShape` + id + `"></span>
|
||||
<span id="dnaDecorationPattern` + id + `"></span>
|
||||
<span id="dnaDecorationAtEye` + id + `"></span>
|
||||
<span id="dnaDecorationMid` + id + `"></span>
|
||||
<span id="dnaDecorationSmall` + id + `"></span>
|
||||
<span id="dnaAnimation` + id + `"></span><br>
|
||||
<ul class="ml-4">
|
||||
<li class="bottomList"><span id="bottomeyetext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomdecorationpatterntext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomanimationtext`
|
||||
+ id + `"></span></li>
|
||||
</ul>
|
||||
<div align="center">SIRE</div>
|
||||
</b>
|
||||
</div>
|
||||
</div>`
|
||||
$('#sireDisplay').empty();
|
||||
$('#sireDisplay').append(boxDiv);
|
||||
};
|
||||
|
||||
function childBox(id) {
|
||||
var boxDiv = `<div style='transform: scaleX(0.8)' id="childBox" class="col-lg-6 m-2 CatalogBox light-b-shadow">
|
||||
<div style='transform: scale(0.8) scaleX(1.2)' class="bird">
|
||||
<div class="tail">
|
||||
<div class="tail_top"></div>
|
||||
<div class="tail_middle"></div>
|
||||
<div class="tail_bottom"></div>
|
||||
</div>
|
||||
<div class="feather">
|
||||
<div class="feather_top"></div>
|
||||
<div class="feather_bottom"></div>
|
||||
</div>
|
||||
<div class="bird_body">
|
||||
<div class="bird_body bird_body_inner"></div>
|
||||
<div class="deco_1"></div>
|
||||
<div class="deco_2"></div>
|
||||
<div class="deco_3"></div>
|
||||
<div class="deco_4"></div>
|
||||
</div>
|
||||
<div class="belly"></div>
|
||||
<div class="face">
|
||||
<div class="eye eye_right">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="eye eye_left">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="beak">
|
||||
<div class="beak_upper"></div>
|
||||
<div class="beak_lower"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<div class="dnaDiv">
|
||||
<b>
|
||||
<div id="idData">
|
||||
ID:
|
||||
<span>` + id + `</span>
|
||||
</div>
|
||||
<div id="genData">
|
||||
GEN:
|
||||
<span id="generation` + id + `"></span>
|
||||
</div><br>
|
||||
<div id="mumData">
|
||||
MUM:
|
||||
<span id="mum` + id + `"></span>
|
||||
</div>
|
||||
<div id="dadData">
|
||||
DAD:
|
||||
<span align="right" id="dad` + id + `"></span><br>
|
||||
</div><br>
|
||||
DNA:
|
||||
<span id="dnaTopFeather` + id + `"></span>
|
||||
<span id="dnaBodyFeather` + id + `"></span>
|
||||
<span id="dnaTopBeak` + id + `"></span>
|
||||
<span id="dnaBottomBeak` + id + `"></span>
|
||||
<span id="dnaEyesShape` + id + `"></span>
|
||||
<span id="dnaDecorationPattern` + id + `"></span>
|
||||
<span id="dnaDecorationAtEye` + id + `"></span>
|
||||
<span id="dnaDecorationMid` + id + `"></span>
|
||||
<span id="dnaDecorationSmall` + id + `"></span>
|
||||
<span id="dnaAnimation` + id + `"></span><br>
|
||||
<ul class="ml-4">
|
||||
<li class="bottomList"><span id="bottomeyetext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomdecorationpatterntext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomanimationtext`
|
||||
+ id + `"></span></li>
|
||||
</ul>
|
||||
<div align="center">NEWBORN!</div>
|
||||
</b>
|
||||
</div>
|
||||
</div>`
|
||||
$('#childDisplay').empty();
|
||||
$('#childDisplay').append(boxDiv);
|
||||
};
|
||||
|
||||
function modalBox(id) {
|
||||
var boxDiv = `<div id="BirdBox` + id + `" class="col-lg-3 CatalogBox m-2 light-b-shadow">
|
||||
<div class="bird">
|
||||
<div class="tail">
|
||||
<div class="tail_top"></div>
|
||||
<div class="tail_middle"></div>
|
||||
<div class="tail_bottom"></div>
|
||||
</div>
|
||||
<div class="feather">
|
||||
<div class="feather_top"></div>
|
||||
<div class="feather_bottom"></div>
|
||||
</div>
|
||||
<div class="bird_body">
|
||||
<div class="bird_body bird_body_inner"></div>
|
||||
<div class="deco_1"></div>
|
||||
<div class="deco_2"></div>
|
||||
<div class="deco_3"></div>
|
||||
<div class="deco_4"></div>
|
||||
</div>
|
||||
<div class="belly"></div>
|
||||
<div class="face">
|
||||
<div class="eye eye_right">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="eye eye_left">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="beak">
|
||||
<div class="beak_upper"></div>
|
||||
<div class="beak_lower"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<div class="dnaDiv">
|
||||
<b>
|
||||
<div id="idData">
|
||||
ID:
|
||||
<span>` + id + `</span>
|
||||
</div>
|
||||
<div id="genData">
|
||||
GEN:
|
||||
<span id="generation` + id + `"></span>
|
||||
</div><br>
|
||||
<div id="mumData">
|
||||
MUM:
|
||||
<span id="mum` + id + `"></span>
|
||||
</div>
|
||||
<div id="dadData">
|
||||
DAD:
|
||||
<span align="right" id="dad` + id + `"></span><br>
|
||||
</div><br>
|
||||
DNA:
|
||||
<span id="dnaTopFeather` + id + `"></span>
|
||||
<span id="dnaBodyFeather` + id + `"></span>
|
||||
<span id="dnaTopBeak` + id + `"></span>
|
||||
<span id="dnaBottomBeak` + id + `"></span>
|
||||
<span id="dnaEyesShape` + id + `"></span>
|
||||
<span id="dnaDecorationPattern` + id + `"></span>
|
||||
<span id="dnaDecorationAtEye` + id + `"></span>
|
||||
<span id="dnaDecorationMid` + id + `"></span>
|
||||
<span id="dnaDecorationSmall` + id + `"></span>
|
||||
<span id="dnaAnimation` + id + `"></span><br>
|
||||
<ul class="ml-4">
|
||||
<li class="bottomList"><span id="bottomeyetext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomdecorationpatterntext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomanimationtext`
|
||||
+ id + `"></span></li>
|
||||
</ul>
|
||||
</b>
|
||||
</div>
|
||||
</div>`
|
||||
$('.row').append(boxDiv);
|
||||
};
|
183
client/assets/js/catalog.js
Normal file
@ -0,0 +1,183 @@
|
||||
var balance;
|
||||
var ids;
|
||||
var onSale;
|
||||
var toDisplay;
|
||||
|
||||
$(document).ready( async () => {//when page is loaded, get latest instance of blockchain
|
||||
await connectWallet();
|
||||
await onlyOwnerAccess();
|
||||
balance = await returnBalance();
|
||||
displayBalance(balance);
|
||||
ids = await getBirdsOfOwner();
|
||||
onSale = await getBirdsOnSale();
|
||||
if (onSale == "") {
|
||||
toDisplay = ids
|
||||
;
|
||||
} else {
|
||||
toDisplay = ids
|
||||
.filter(x => !onSale.includes(x));//all birds of this user not on sale
|
||||
}
|
||||
await buildCatalog(toDisplay);
|
||||
activateMouseListeners();
|
||||
});
|
||||
|
||||
function displayBalance(balance) {
|
||||
$('#fundsAvailable').html("You have " + balance + " ETH available from bird sales. ");
|
||||
};
|
||||
|
||||
function appendBirdToCatalog(dna, id) {
|
||||
catalogBox(id); //class is defined and set in rendering.js
|
||||
renderBird(`#BirdBox${id}`, birdDna(dna), id);
|
||||
};
|
||||
|
||||
function catalogBox(id) {
|
||||
var boxDiv = `<div id="BirdBox` + id + `" class="col-lg-3 catalogBox m-2 light-b-shadow">
|
||||
<div class="bird">
|
||||
<div class="tail">
|
||||
<div class="tail_top"></div>
|
||||
<div class="tail_middle"></div>
|
||||
<div class="tail_bottom"></div>
|
||||
</div>
|
||||
<div class="feather">
|
||||
<div class="feather_top"></div>
|
||||
<div class="feather_bottom"></div>
|
||||
</div>
|
||||
<div class="bird_body">
|
||||
<div class="bird_body bird_body_inner"></div>
|
||||
<div class="deco_1"></div>
|
||||
<div class="deco_2"></div>
|
||||
<div class="deco_3"></div>
|
||||
<div class="deco_4"></div>
|
||||
</div>
|
||||
<div class="belly"></div>
|
||||
<div class="face">
|
||||
<div class="eye eye_right">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="eye eye_left">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="beak">
|
||||
<div class="beak_upper"></div>
|
||||
<div class="beak_lower"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<div class="dnaDiv">
|
||||
<b>
|
||||
<div id="idData">
|
||||
ID:
|
||||
<span>` + id + `</span>
|
||||
</div>
|
||||
<div id="genData">
|
||||
GEN:
|
||||
<span id="generation` + id + `"></span>
|
||||
</div><br>
|
||||
<div id="mumData">
|
||||
MUM:
|
||||
<span id="mum` + id + `"></span>
|
||||
</div>
|
||||
<div id="dadData">
|
||||
DAD:
|
||||
<span align="right" id="dad` + id + `"></span><br>
|
||||
</div><br>
|
||||
DNA:
|
||||
<span id="dnaTopFeather` + id + `"></span>
|
||||
<span id="dnaBodyFeather` + id + `"></span>
|
||||
<span id="dnaTopBeak` + id + `"></span>
|
||||
<span id="dnaBottomBeak` + id + `"></span>
|
||||
<span id="dnaEyesShape` + id + `"></span>
|
||||
<span id="dnaDecorationPattern` + id + `"></span>
|
||||
<span id="dnaDecorationAtEye` + id + `"></span>
|
||||
<span id="dnaDecorationMid` + id + `"></span>
|
||||
<span id="dnaDecorationSmall` + id + `"></span>
|
||||
<span id="dnaAnimation` + id + `"></span><br>
|
||||
<ul class="ml-4">
|
||||
<li class="bottomList"><span id="bottomeyetext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomdecorationpatterntext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomanimationtext`
|
||||
+ id + `"></span></li>
|
||||
</ul>
|
||||
</b>
|
||||
<div class="input-group mb-3">
|
||||
<input id="birdPrice` + id + `" type="text"
|
||||
class="form-control" placeholder="Amount in ETH"
|
||||
aria-label="Amount in ETH" aria-describedby="button-addon2">
|
||||
<div class="input-group-append">
|
||||
<button id="offerButton` + id + `"
|
||||
class="btn btn-success submitButton"
|
||||
type="button" id="button-addon2">Submit Offer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
$('.row').append(boxDiv);
|
||||
};
|
||||
|
||||
//Listener for withdraw button
|
||||
$('#withdrawButton').click(async ()=>{
|
||||
if(balance > 0) {
|
||||
$('#withdrawButton').hide();
|
||||
await withdraw();
|
||||
location.reload();
|
||||
};
|
||||
});
|
||||
|
||||
//Listeners for offer buttons
|
||||
function activateCatalogEventListeners() {
|
||||
$(`[id^='birdPrice']`).keypress(async function(e) {
|
||||
if ( e.which == 13 ) {//both enter buttons have '13'.
|
||||
await initializeMarketplace();//allow Marketplace contract to handle offers.
|
||||
var id = $(this).attr("id").substring(9);//extract id from HTML.
|
||||
var price = $(this).val();//get price of the bird with the same id as the button
|
||||
if (isNaN(price)) {
|
||||
alert("Please enter a number!")
|
||||
} else if (price <= 0) {
|
||||
alert("Please enter a positive number!")
|
||||
} else{
|
||||
$(`#birdPrice${id}`).hide();
|
||||
$(`#offerButton${id}`).hide();
|
||||
await sellBird(price, id);
|
||||
$(`#BirdBox${id}`).remove();//remove bird from DOM
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
$(`[id^='offerButton']`).on("click", async function() {
|
||||
await initializeMarketplace();//allow Marketplace contract to handle offers.
|
||||
var id = $(this).attr("id").substring(11);//extract id from HTML.
|
||||
var price = $(`#birdPrice${id}`).val();//get price of the bird with the same id as the button
|
||||
if (isNaN(price)) {
|
||||
alert("Please enter a number!")
|
||||
} else if (price <= 0) {
|
||||
alert("Please enter a positive number!")
|
||||
} else{
|
||||
$(`#birdPrice${id}`).hide();
|
||||
$(`#offerButton${id}`).hide();
|
||||
await sellBird(price, id);
|
||||
$(`#BirdBox${id}`).remove();//remove bird from DOM
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
//Listener for eye animation
|
||||
function activateMouseListeners() {
|
||||
$('.CatalogBox').on("mousemove", () => {
|
||||
var eyeballs = $('.eyesFollow');
|
||||
document.onmousemove = function(event) {
|
||||
var x = event.clientX * 65 / window.innerWidth + "%";
|
||||
var y = event.clientY * 65 / window.innerHeight + "%";
|
||||
for (let i = 0; i < eyeballs.length; i++) {
|
||||
eyeballs[i].style.left = x;
|
||||
eyeballs[i].style.top = y;
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
106
client/assets/js/colors.js
Normal file
@ -0,0 +1,106 @@
|
||||
var colors = {
|
||||
00: "ae494f",
|
||||
01: "9a3031",
|
||||
02: "8cd42e",
|
||||
03: "a0417a",
|
||||
04: "91c656",
|
||||
05: "299f7a",
|
||||
06: "c65d1e",
|
||||
07: "b2bbd6",
|
||||
08: "2d4024",
|
||||
09: "4b5715",
|
||||
10: "ffcc80",
|
||||
11: "3f1174",
|
||||
12: "b22a90",
|
||||
13: "fff3e0",
|
||||
14: "4c858b",
|
||||
15: "18bebe",
|
||||
16: "b5044b",
|
||||
17: "d6b1d4",
|
||||
18: "fecb40",
|
||||
19: "748882",
|
||||
20: "4a3c95",
|
||||
21: "482916",
|
||||
22: "267bf0",
|
||||
23: "5af7e2",
|
||||
24: "adeacc",
|
||||
25: "cf2b03",
|
||||
26: "b3c459",
|
||||
27: "353f99",
|
||||
28: "5d4993",
|
||||
29: "ba8d15",
|
||||
30: "da2457",
|
||||
31: "ff17fe",
|
||||
32: "d6e81d",
|
||||
33: "daf2db",
|
||||
34: "19b510",
|
||||
35: "ab060c",
|
||||
36: "b7c36a",
|
||||
37: "8cb175",
|
||||
38: "bdce32",
|
||||
39: "f2e0ba",
|
||||
40: "a2f8a5",
|
||||
41: "64bf50",
|
||||
42: "f1a771",
|
||||
43: "4982a9",
|
||||
44: "f66c41",
|
||||
45: "2fe802",
|
||||
46: "bda142",
|
||||
47: "8342ff",
|
||||
48: "2b4ab4",
|
||||
49: "ad4595",
|
||||
50: "bae4f9",
|
||||
51: "b76d01",
|
||||
52: "8e8207",
|
||||
53: "285b9f",
|
||||
54: "c4422a",
|
||||
55: "ce000f",
|
||||
56: "e3a0cc",
|
||||
57: "ce000f",
|
||||
58: "656ccf",
|
||||
59: "7c25f4",
|
||||
60: "1e18d1",
|
||||
61: "688a7d",
|
||||
62: "1fe786",
|
||||
63: "425716",
|
||||
64: "4ac043",
|
||||
65: "547836",
|
||||
66: "24a216",
|
||||
67: "fd9bba",
|
||||
68: "24894d",
|
||||
69: "c54b03",
|
||||
70: "6fbdce",
|
||||
71: "e28810",
|
||||
72: "8805fb",
|
||||
73: "e28810",
|
||||
74: "c52f14",
|
||||
75: "e31c54",
|
||||
76: "d010eb",
|
||||
77: "b83436",
|
||||
78: "c294b6",
|
||||
79: "564a6c",
|
||||
80: "531bcf",
|
||||
81: "e9b90d",
|
||||
82: "3cd2ef",
|
||||
83: "e9b90d",
|
||||
84: "aa2639",
|
||||
85: "86be6c",
|
||||
86: "e62102",
|
||||
87: "5471fc",
|
||||
88: "5c0899",
|
||||
89: "703c75",
|
||||
90: "9a8e8f",
|
||||
91: "8b9307",
|
||||
92: "fcbc82",
|
||||
93: "ea5978",
|
||||
94: "b8e370",
|
||||
95: "43474b",
|
||||
96: "262d2b",
|
||||
97: "ddd67e",
|
||||
98: "344867",
|
||||
99: "aacc32"
|
||||
}
|
||||
|
||||
function allColors(){
|
||||
return colors;
|
||||
};
|
4
client/assets/js/index.js
Normal file
@ -0,0 +1,4 @@
|
||||
$(document).ready( async () => {//when page is loaded, get latest instance of blockchain
|
||||
await connectWallet();
|
||||
await onlyOwnerAccess();
|
||||
});
|
2
client/assets/js/jquery-3.5.1.min.js
vendored
Normal file
254
client/assets/js/market.js
Normal file
@ -0,0 +1,254 @@
|
||||
var ids;
|
||||
var onSale;
|
||||
var inMarket;
|
||||
var inOffers;
|
||||
|
||||
$(document).ready( async () => {//when page is loaded, get latest instance of blockchain
|
||||
await connectWallet();
|
||||
await onlyOwnerAccess();
|
||||
ids = await getBirdsOfOwner();
|
||||
onSale = await getBirdsOnSale();
|
||||
inMarket = onSale.filter(x => !ids.includes(x));//offers of other users
|
||||
inMarket = inMarket.filter(x => !["0"].includes(x));//remove Bird0
|
||||
inOffers = onSale.filter(x => ids.includes(x));//user's offers
|
||||
await buildOffers(inOffers);//build offers
|
||||
await buildMarket(inMarket);//build market
|
||||
activateMouseListeners();
|
||||
});
|
||||
|
||||
async function appendBirdToMarket(dna, id) {
|
||||
var price = await getPrice(id);
|
||||
marketBox(price, id);
|
||||
renderBird(`#BirdBox${id}`, birdDna(dna), id);
|
||||
};
|
||||
|
||||
async function appendBirdToOffers(dna, id) {
|
||||
var price = await getPrice(id);
|
||||
offerBox(price, id);
|
||||
renderBird(`#BirdBox${id}`, birdDna(dna), id);
|
||||
};
|
||||
|
||||
function marketBox(price, id) {//used for offers of other users
|
||||
var boxDiv = `<div id="BirdBox` + id + `" class="col-lg-3 buyBox CatalogBox m-2 light-b-shadow">
|
||||
<div class="bird">
|
||||
<div class="tail">
|
||||
<div class="tail_top"></div>
|
||||
<div class="tail_middle"></div>
|
||||
<div class="tail_bottom"></div>
|
||||
</div>
|
||||
<div class="feather">
|
||||
<div class="feather_top"></div>
|
||||
<div class="feather_bottom"></div>
|
||||
</div>
|
||||
<div class="bird_body">
|
||||
<div class="bird_body bird_body_inner"></div>
|
||||
<div class="deco_1"></div>
|
||||
<div class="deco_2"></div>
|
||||
<div class="deco_3"></div>
|
||||
<div class="deco_4"></div>
|
||||
</div>
|
||||
<div class="belly"></div>
|
||||
<div class="face">
|
||||
<div class="eye eye_right">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="eye eye_left">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="beak">
|
||||
<div class="beak_upper"></div>
|
||||
<div class="beak_lower"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<div class="dnaDiv">
|
||||
<b>
|
||||
<div id="idData">
|
||||
ID:
|
||||
<span>` + id + `</span>
|
||||
</div>
|
||||
<div id="genData">
|
||||
GEN:
|
||||
<span id="generation` + id + `"></span>
|
||||
</div><br>
|
||||
<div id="mumData">
|
||||
MUM:
|
||||
<span id="mum` + id + `"></span>
|
||||
</div>
|
||||
<div id="dadData">
|
||||
DAD:
|
||||
<span align="right" id="dad` + id + `"></span><br>
|
||||
</div><br>
|
||||
DNA:
|
||||
<span id="dnaTopFeather` + id + `"></span>
|
||||
<span id="dnaBodyFeather` + id + `"></span>
|
||||
<span id="dnaTopBeak` + id + `"></span>
|
||||
<span id="dnaBottomBeak` + id + `"></span>
|
||||
<span id="dnaEyesShape` + id + `"></span>
|
||||
<span id="dnaDecorationPattern` + id + `"></span>
|
||||
<span id="dnaDecorationAtEye` + id + `"></span>
|
||||
<span id="dnaDecorationMid` + id + `"></span>
|
||||
<span id="dnaDecorationSmall` + id + `"></span>
|
||||
<span id="dnaAnimation` + id + `"></span><br>
|
||||
<ul class="ml-4">
|
||||
<li class="bottomList"><span id="bottomeyetext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomdecorationpatterntext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomanimationtext`
|
||||
+ id + `"></span></li>
|
||||
</ul>
|
||||
<div align="center">
|
||||
ASKING PRICE: ` + price + ` ETH
|
||||
</div>
|
||||
</b>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-append">
|
||||
<button id="buyButton` + id + `"
|
||||
class="btn btn-success buyButton rounded-lg"
|
||||
type="button" id="button-addon2">Buy Bird</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
$('.marketOffers').append(boxDiv);
|
||||
};
|
||||
|
||||
function offerBox(price, id) {//used for offers of current user
|
||||
var boxDiv = `<div id="BirdBox` + id + `" class="col-lg-3 offerBox CatalogBox m-2 light-b-shadow">
|
||||
<div class="bird">
|
||||
<div class="tail">
|
||||
<div class="tail_top"></div>
|
||||
<div class="tail_middle"></div>
|
||||
<div class="tail_bottom"></div>
|
||||
</div>
|
||||
<div class="feather">
|
||||
<div class="feather_top"></div>
|
||||
<div class="feather_bottom"></div>
|
||||
</div>
|
||||
<div class="bird_body">
|
||||
<div class="bird_body bird_body_inner"></div>
|
||||
<div class="deco_1"></div>
|
||||
<div class="deco_2"></div>
|
||||
<div class="deco_3"></div>
|
||||
<div class="deco_4"></div>
|
||||
</div>
|
||||
<div class="belly"></div>
|
||||
<div class="face">
|
||||
<div class="eye eye_right">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="eye eye_left">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="beak">
|
||||
<div class="beak_upper"></div>
|
||||
<div class="beak_lower"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<div class="dnaDiv">
|
||||
<b>
|
||||
<div id="idData">
|
||||
ID:
|
||||
<span>` + id + `</span>
|
||||
</div>
|
||||
<div id="genData">
|
||||
GEN:
|
||||
<span id="generation` + id + `"></span>
|
||||
</div><br>
|
||||
<div id="mumData">
|
||||
MUM:
|
||||
<span id="mum` + id + `"></span>
|
||||
</div>
|
||||
<div id="dadData">
|
||||
DAD:
|
||||
<span align="right" id="dad` + id + `"></span><br>
|
||||
</div><br>
|
||||
DNA:
|
||||
<span id="dnaTopFeather` + id + `"></span>
|
||||
<span id="dnaBodyFeather` + id + `"></span>
|
||||
<span id="dnaTopBeak` + id + `"></span>
|
||||
<span id="dnaBottomBeak` + id + `"></span>
|
||||
<span id="dnaEyesShape` + id + `"></span>
|
||||
<span id="dnaDecorationPattern` + id + `"></span>
|
||||
<span id="dnaDecorationAtEye` + id + `"></span>
|
||||
<span id="dnaDecorationMid` + id + `"></span>
|
||||
<span id="dnaDecorationSmall` + id + `"></span>
|
||||
<span id="dnaAnimation` + id + `"></span><br>
|
||||
<ul class="ml-4">
|
||||
<li class="bottomList"><span id="bottomeyetext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomdecorationpatterntext`
|
||||
+ id + `"></span></li>
|
||||
<li class="bottomList"><span id="bottomanimationtext`
|
||||
+ id + `"></span></li>
|
||||
</ul>
|
||||
<div align="center">
|
||||
ASKING PRICE: ` + price + ` ETH
|
||||
</div>
|
||||
</b>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-append">
|
||||
<button id="cancelButton` + id + `"
|
||||
class="btn btn-danger cancelButton rounded-lg"
|
||||
type="button" id="button-addon2">Cancel Offer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
$('.myOffers').append(boxDiv);
|
||||
};
|
||||
|
||||
//Listener for eye animation
|
||||
function activateMouseListeners() {
|
||||
$('.CatalogBox').on("mousemove", () => {
|
||||
var eyeballs = $('.eyesFollow');
|
||||
document.onmousemove = function(event) {
|
||||
var x = event.clientX * 65 / window.innerWidth + "%";
|
||||
var y = event.clientY * 65 / window.innerHeight + "%";
|
||||
for (let i = 0; i < eyeballs.length; i++) {
|
||||
eyeballs[i].style.left = x;
|
||||
eyeballs[i].style.top = y;
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
//Listeners for buttons
|
||||
async function activateBuyButtonListeners() {
|
||||
if(await checkPause()) {
|
||||
$(`[id^='buyButton']`).hide();
|
||||
} else {
|
||||
$(`[id^='buyButton']`).show();
|
||||
$(`[id^='buyButton']`).on("click", async function() {
|
||||
await initializeMarketplace();
|
||||
//make sure marketplace contract is approved as operator for user
|
||||
var id = $(this).attr("id").substring(9);//extract bird ID from HTML
|
||||
var price = await getPrice(id);
|
||||
$(`#buyButton${id}`).hide();
|
||||
await buyBird(price, id);
|
||||
$(`#BirdBox${id}`).remove();//remove bird from DOM
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
function activateCancelButtonListeners() {
|
||||
$(`[id^='cancelButton']`).on("click", async function() {
|
||||
await initializeMarketplace();
|
||||
//make sure marketplace contract is approved as operator for user
|
||||
var id = $(this).attr("id").substring(12);//extract bird ID from HTML
|
||||
$(`#cancelButton${id}`).hide();
|
||||
await removeOffer(id);
|
||||
$(`#BirdBox${id}`).remove();//remove bird from DOM
|
||||
});
|
||||
};
|
431
client/assets/js/rendering.js
Normal file
@ -0,0 +1,431 @@
|
||||
var colors = Object.values(allColors());
|
||||
|
||||
function birdDna(dna) {
|
||||
var dnaObject = {
|
||||
"topFeatherColor": dna.genes.substring(0, 2),
|
||||
"bodyFeatherColor": dna.genes.substring(2, 4),
|
||||
"topBeakColor": dna.genes.substring(4, 6),
|
||||
"bottomBeakColor": dna.genes.substring(6, 8),
|
||||
"eyesShape": parseInt(dna.genes.substring(8, 9)),
|
||||
"decorationPattern": parseInt(dna.genes.substring(9, 10)),
|
||||
"decorationColor": dna.genes.substring(10, 12),
|
||||
"decorationMidColor": dna.genes.substring(12, 14),
|
||||
"decorationSmallColor": dna.genes.substring(14, 16),
|
||||
"animation": parseInt(dna.genes.substring(16, 17)),
|
||||
"generation": dna.generation,
|
||||
"mum": dna.mumId,
|
||||
"dad": dna.dadId
|
||||
};
|
||||
return dnaObject;
|
||||
};
|
||||
|
||||
function renderBird(boxId, dna, id){
|
||||
topFeatherColor(boxId, colors[dna.topFeatherColor], dna.topFeatherColor, id);
|
||||
bodyFeatherColor(boxId, colors[dna.bodyFeatherColor],dna.bodyFeatherColor, id);
|
||||
topBeakColor(boxId, colors[dna.topBeakColor],dna.topBeakColor, id);
|
||||
bottomBeakColor(boxId, colors[dna.bottomBeakColor],dna.bottomBeakColor, id);
|
||||
eyesVariation(boxId, dna.eyesShape, id);
|
||||
decorationVariation(boxId, dna.decorationPattern, id);
|
||||
decorationMainColor(boxId, colors[dna.decorationColor],dna.decorationColor, id);
|
||||
middleColor(boxId, colors[dna.decorationMidColor],dna.decorationMidColor, id);
|
||||
smallColor(boxId, colors[dna.decorationSmallColor],dna.decorationSmallColor, id);
|
||||
animationVariation(boxId, dna.animation, id);
|
||||
printGeneration(dna.generation, id);
|
||||
printMum(dna.mum, id);
|
||||
printDad(dna.dad, id);
|
||||
};
|
||||
|
||||
function topFeatherColor(boxId, color, code, id) {
|
||||
$(`${boxId} .feather_top`).css('background', '#' + color);
|
||||
$(`${boxId} .feather_bottom`).css('background', '#' + color);
|
||||
$('#dnaTopFeather' + id).html(code);
|
||||
};
|
||||
|
||||
function bodyFeatherColor(boxId, color, code, id) {
|
||||
$(`${boxId} .bird_body_inner`).css('background', '#' + color);
|
||||
$('#dnaBodyFeather' + id).html(code);
|
||||
};
|
||||
|
||||
function topBeakColor(boxId, color, code, id) {
|
||||
$(`${boxId} .beak_upper`).css('background', '#' + color);
|
||||
$('#dnaTopBeak' + id).html(code);
|
||||
};
|
||||
|
||||
function bottomBeakColor(boxId, color, code, id) {
|
||||
$(`${boxId} .beak_lower`).css('background', '#' + color);
|
||||
$('#dnaBottomBeak' + id).html(code);
|
||||
};
|
||||
|
||||
function eyesVariation(boxId, num, id) {
|
||||
$('#dnaEyesShape' + id).html(num);
|
||||
switch (num) {
|
||||
case 0:
|
||||
basicEyes(boxId);
|
||||
$('#bottomeyetext' + id).html('Basic Eyes');
|
||||
break;
|
||||
case 1:
|
||||
basicEyes(boxId);
|
||||
$('#bottomeyetext' + id).html('Chilled Eyes');
|
||||
eyesType1(boxId);
|
||||
break;
|
||||
case 2:
|
||||
basicEyes(boxId);
|
||||
$('#bottomeyetext' + id).html('Eyes Turned Upwards');
|
||||
eyesType2(boxId);
|
||||
break;
|
||||
case 3:
|
||||
basicEyes(boxId);
|
||||
$('#bottomeyetext' + id).html('Eyes Turned Right');
|
||||
eyesType3(boxId);
|
||||
break;
|
||||
case 4:
|
||||
basicEyes(boxId);
|
||||
$('#bottomeyetext' + id).html('Eyes Turned Left');
|
||||
eyesType4(boxId);
|
||||
break;
|
||||
case 5:
|
||||
basicEyes(boxId);
|
||||
$('#bottomeyetext' + id).html('Dazzled Eyes');
|
||||
eyesType5(boxId);
|
||||
break;
|
||||
case 6:
|
||||
basicEyes(boxId);
|
||||
$('#bottomeyetext' + id).html('Eye Slits');
|
||||
eyesType6(boxId);
|
||||
break;
|
||||
case 7:
|
||||
basicEyes(boxId);
|
||||
$('#bottomeyetext' + id).html('Masked Eyes');
|
||||
eyesType7(boxId);
|
||||
break;
|
||||
default:
|
||||
basicEyes(boxId);
|
||||
$('#bottomeyetext' + id).html('Basic Eyes');
|
||||
};
|
||||
};
|
||||
|
||||
function basicEyes(boxId) {
|
||||
$(`${boxId} .eye`).css({'border-top': 'none', 'border-bottom': 'none',
|
||||
'border-left': 'none', 'border-right': 'none', 'border': '0.9em black solid'});
|
||||
$(`${boxId} .eye_right .eyebrow`).css({'left': '-1em', 'top': '-1.5em'});
|
||||
$(`${boxId} .eye_left .eyebrow`).css({'left': '-3em', 'top': '-1.5em'});
|
||||
$(`${boxId} .eye_right .pupil`).css({'left': '1.5em', 'top': '3em'});
|
||||
$(`${boxId} .eye_left .pupil`).css({'left': '5em', 'top': '3em'});
|
||||
};
|
||||
|
||||
function eyesType1(boxId) {//Chilled
|
||||
$(`${boxId} .eye`).css('border-top', '4em solid');
|
||||
$(`${boxId} .eye_right .eyebrow`).css({'left': '-1em', 'top': '-4.5em'});
|
||||
$(`${boxId} .eye_left .eyebrow`).css({'left': '-3em', 'top': '-4.5em'});
|
||||
$(`${boxId} .eye_right .pupil`).css({'left': '1.5em', 'top': '1em'});
|
||||
$(`${boxId} .eye_left .pupil`).css({'left': '5em', 'top': '1em'});
|
||||
};
|
||||
|
||||
function eyesType2(boxId) {//Up
|
||||
$(`${boxId} .eye`).css('border-bottom', '4em solid');
|
||||
$(`${boxId} .eye_right .eyebrow`).css({'left': '-1em', 'top': '-2em'});
|
||||
$(`${boxId} .eye_left .eyebrow`).css({'left': '-3em', 'top': '-2em'});
|
||||
$(`${boxId} .eye_right .pupil`).css({'left': '1.5em', 'top': '2em'});
|
||||
$(`${boxId} .eye_left .pupil`).css({'left': '5em', 'top': '2em'});
|
||||
};
|
||||
|
||||
function eyesType3(boxId) {//Right
|
||||
$(`${boxId} .eye`).css('border-left', '2.5em solid');
|
||||
$(`${boxId} .eye_right .eyebrow`).css({'left': '-1em', 'top': '-1.5em'});
|
||||
$(`${boxId} .eye_left .eyebrow`).css({'left': '-3em', 'top': '-1.5em'});
|
||||
$(`${boxId} .eye_right .pupil`).css({'left': '5em', 'top': '3em'});
|
||||
$(`${boxId} .eye_left .pupil`).css({'left': '5em', 'top': '3em'});
|
||||
};
|
||||
|
||||
function eyesType4(boxId) {//Left
|
||||
$(`${boxId} .eye`).css('border-right', '2.5em solid');
|
||||
$(`${boxId} .eye_right .eyebrow`).css({'left': '-1em', 'top': '-1.5em'});
|
||||
$(`${boxId} .eye_left .eyebrow`).css({'left': '-3em', 'top': '-1.5em'});
|
||||
$(`${boxId} .eye_right .pupil`).css({'left': '0em', 'top': '3em'});
|
||||
$(`${boxId} .eye_left .pupil`).css({'left': '0em', 'top': '3em'});
|
||||
};
|
||||
|
||||
function eyesType5(boxId) {//Dazzled
|
||||
$(`${boxId} .eye`).css({'border-top': '4em solid', 'border-bottom': '4em solid'});
|
||||
$(`${boxId} .eye_right .eyebrow`).css({'left': '-1em', 'top': '-5.5em'});
|
||||
$(`${boxId} .eye_left .eyebrow`).css({'left': '-3em', 'top': '-5.5em'});
|
||||
$(`${boxId} .eye_right .pupil`).css({'left': '3em', 'top': '0em'});
|
||||
$(`${boxId} .eye_left .pupil`).css({'left': '3em', 'top': '0em'});
|
||||
};
|
||||
|
||||
function eyesType6(boxId) {//Slit
|
||||
$(`${boxId} .eye`).css({'border-top': '4em solid', 'border-left': '4em solid',
|
||||
'border-right': '4em solid'});
|
||||
$(`${boxId} .eye_right .eyebrow`).css({'left': '-4em', 'top': '-5em'});
|
||||
$(`${boxId} .eye_left .eyebrow`).css({'left': '-6em', 'top': '-5em'});
|
||||
$(`${boxId} .eye_right .pupil`).css({'left': '-0.1em', 'top': '1em'});
|
||||
$(`${boxId} .eye_left .pupil`).css({'left': '-0.1em', 'top': '1em'});
|
||||
};
|
||||
|
||||
function eyesType7(boxId) {//Mask
|
||||
$(`${boxId} .eye`).css('border', '3em solid');
|
||||
$(`${boxId} .eye_right .eyebrow`).css({'left': '-3em', 'top': '-5em'});
|
||||
$(`${boxId} .eye_left .eyebrow`).css({'left': '-5em', 'top': '-5em'});
|
||||
$(`${boxId} .eye_right .pupil`).css({'left': '1em', 'top': '1em'});
|
||||
$(`${boxId} .eye_left .pupil`).css({'left': '1em', 'top': '1em'});
|
||||
};
|
||||
|
||||
function decorationVariation(boxId, num, id) {
|
||||
$('#dnaDecorationPattern' + id).html(num)
|
||||
switch (num) {
|
||||
case 0:
|
||||
$('#bottomdecorationpatterntext' + id).html('Basic Decoration');
|
||||
resetDecoration(boxId);
|
||||
break;
|
||||
case 1:
|
||||
resetDecoration(boxId);
|
||||
$('#bottomdecorationpatterntext' + id).html('Large Spots');
|
||||
decorationType1(boxId);
|
||||
break;
|
||||
case 2:
|
||||
resetDecoration(boxId);
|
||||
$('#bottomdecorationpatterntext' + id).html('Maximum Spots');
|
||||
decorationType2(boxId);
|
||||
break;
|
||||
case 3:
|
||||
resetDecoration(boxId);
|
||||
$('#bottomdecorationpatterntext' + id).html('Decoration only at Eyes');
|
||||
decorationType3(boxId);
|
||||
break;
|
||||
case 4:
|
||||
resetDecoration(boxId);
|
||||
$('#bottomdecorationpatterntext' + id).html('Decoration on Back only');
|
||||
decorationType4(boxId);
|
||||
break;
|
||||
case 5:
|
||||
resetDecoration(id);
|
||||
$('#bottomdecorationpatterntext' + id).html('No Decoration');
|
||||
decorationType5(boxId);
|
||||
break;
|
||||
case 6:
|
||||
resetDecoration(boxId);
|
||||
$('#bottomdecorationpatterntext' + id).html('Cross Decoration');
|
||||
decorationType6(boxId);
|
||||
break;
|
||||
case 7:
|
||||
resetDecoration(boxId);
|
||||
$('#bottomdecorationpatterntext' + id).html('Cross & Eyes Decoration');
|
||||
decorationType7(boxId);
|
||||
break;
|
||||
default:
|
||||
resetDecoration(boxId);
|
||||
$('#bottomdecorationpatterntext' + id).html('Basic Decoration');
|
||||
};
|
||||
};
|
||||
|
||||
function resetDecoration(boxId) {
|
||||
$(`${boxId} .deco_1`).css({'display': 'initial', 'transform':
|
||||
'rotate(-25deg) scaleY(1) translateX(0em) translateY(0em)'});
|
||||
$(`${boxId} .deco_2`).css({'display': 'initial', 'transform':
|
||||
'rotate(-15deg) scaleY(1) translateX(0em) translateY(0em)'});
|
||||
$(`${boxId} .deco_3`).css({'display': 'initial', 'transform':
|
||||
'rotate(-10deg) scaleY(1) translateY(0em)'});
|
||||
$(`${boxId} .deco_4`).css({'display': 'initial', 'transform':
|
||||
'rotate(-10deg) scaleY(1) translateY(0em)'});
|
||||
};
|
||||
|
||||
function decorationType1(boxId) {//Large
|
||||
$(`${boxId} .deco_1`).css('transform', 'rotate(-25deg) scaleY(2)');
|
||||
$(`${boxId} .deco_2`).css('transform', 'rotate(-15deg) scaleY(2)');
|
||||
$(`${boxId} .deco_3`).css('transform', 'rotate(-10deg) scaleY(2)');
|
||||
$(`${boxId} .deco_4`).css('transform', 'rotate(-10deg) scaleY(2)');
|
||||
};
|
||||
|
||||
function decorationType2(boxId) {//Max
|
||||
$(`${boxId} .deco_1`).css('transform', 'rotate(-25deg) scaleY(3) translateY(-2.5em)');
|
||||
$(`${boxId} .deco_2`).css('transform', 'rotate(-15deg) scaleY(3) translateY(-2.5em)');
|
||||
$(`${boxId} .deco_3`).css('transform', 'rotate(-10deg) scaleY(3) translateY(-2.5em)');
|
||||
$(`${boxId} .deco_4`).css('transform', 'rotate(-10deg) scaleY(3) translateY(-1.8em)');
|
||||
};
|
||||
|
||||
function decorationType3(boxId) {//Eyes Only
|
||||
$(`${boxId} .deco_1`).css('display', 'none');
|
||||
$(`${boxId} .deco_2`).css('display', 'none');
|
||||
$(`${boxId} .deco_3`).css('transform', 'rotate(-10deg) scaleY(3) translateY(-2.5em)');
|
||||
$(`${boxId} .deco_4`).css('transform', 'rotate(-10deg) scaleY(3) translateY(-1.8em)');
|
||||
};
|
||||
|
||||
function decorationType4(boxId) {//Back Only
|
||||
$(`${boxId} .deco_1`).css('transform', 'rotate(-25deg) scaleY(3) translateY(-2.5em)');
|
||||
$(`${boxId} .deco_2`).css('transform', 'rotate(-15deg) scaleY(3) translateY(-2.5em)');
|
||||
$(`${boxId} .deco_3`).css('display', 'none');
|
||||
$(`${boxId} .deco_4`).css('display', 'none');
|
||||
};
|
||||
|
||||
function decorationType5(boxId) {//None
|
||||
$(`${boxId} .deco_1`).css('display', 'none');
|
||||
$(`${boxId} .deco_2`).css('display', 'none');
|
||||
$(`${boxId} .deco_3`).css('display', 'none');
|
||||
$(`${boxId} .deco_4`).css('display', 'none');
|
||||
};
|
||||
|
||||
function decorationType6(boxId) {//Cross
|
||||
$(`${boxId} .deco_1`).css('transform',
|
||||
'rotate(90deg) scaleY(3) translateX(-9em) translateY(-0.5em)');
|
||||
$(`${boxId} .deco_2`).css('transform',
|
||||
'rotate(0deg) scaleY(3) translateX(-3.5em) translateY(-2.5em)');
|
||||
$(`${boxId} .deco_3`).css('display', 'none');
|
||||
$(`${boxId} .deco_4`).css('display', 'none');
|
||||
}
|
||||
;
|
||||
function decorationType7(boxId) {//Cross & Eyes
|
||||
$(`${boxId} .deco_1`).css('transform',
|
||||
'rotate(90deg) scaleY(3) translateX(-9em) translateY(-0.5em)');
|
||||
$(`${boxId} .deco_2`).css('transform',
|
||||
'rotate(0deg) scaleY(3) translateX(-3.5em) translateY(-2.5em)');
|
||||
$(`${boxId} .deco_3`).css('transform', 'rotate(-10deg) scaleY(2)');
|
||||
$(`${boxId} .deco_4`).css('transform', 'rotate(-10deg) scaleY(2)');
|
||||
};
|
||||
|
||||
function decorationMainColor(boxId, color, code, id) {
|
||||
$(`${boxId} .deco_3`, `${boxId} .deco_4`).css('background', '#' + color);
|
||||
$('#dnaDecorationAtEye' + id).html(code);
|
||||
};
|
||||
|
||||
function middleColor(boxId, color, code, id) {
|
||||
$(`${boxId} .deco_2`).css('background', '#' + color);
|
||||
$('#dnaDecorationMid' + id).html(code);
|
||||
};
|
||||
|
||||
function smallColor(boxId, color, code, id) {
|
||||
$(`${boxId} .deco_1`).css('background', '#' + color);
|
||||
$('#dnaDecorationSmall' + id).html(code);
|
||||
};
|
||||
|
||||
function animationVariation(boxId, num, id) {
|
||||
$('#dnaAnimation' + id).html(num);
|
||||
switch (num) {
|
||||
case 0:
|
||||
resetAnimation(boxId);
|
||||
$('#bottomanimationtext' + id).html('No animation');
|
||||
break;
|
||||
case 1:
|
||||
resetAnimation(boxId);
|
||||
$('#bottomanimationtext' + id).html('Animation: Kick');
|
||||
animationType1(boxId);
|
||||
break;
|
||||
case 2:
|
||||
resetAnimation(boxId);
|
||||
$('#bottomanimationtext' + id).html('Animation: Float');
|
||||
animationType2(boxId);
|
||||
break;
|
||||
case 3:
|
||||
resetAnimation(boxId);
|
||||
$('#bottomanimationtext' + id).html('Animation: Compress');
|
||||
animationType3(boxId);
|
||||
break;
|
||||
case 4:
|
||||
resetAnimation(boxId);
|
||||
$('#bottomanimationtext' + id).html('Animation: Speak');
|
||||
animationType4(boxId);
|
||||
break;
|
||||
case 5:
|
||||
resetAnimation(boxId);
|
||||
$('#bottomanimationtext' + id).html('Animation: Wag');
|
||||
animationType5(boxId);
|
||||
break;
|
||||
case 6:
|
||||
resetAnimation(boxId);
|
||||
$('#bottomanimationtext' + id).html('Animation: Attention');
|
||||
animationType6(boxId);
|
||||
break;
|
||||
case 7:
|
||||
resetAnimation(boxId);
|
||||
$('#bottomanimationtext' + id).html('Combi Animation');
|
||||
animationType7(boxId);
|
||||
break;
|
||||
case 8:
|
||||
resetAnimation(boxId);
|
||||
$('#bottomanimationtext' + id).html('Eyes Follow Mouse');
|
||||
animationType8(boxId);
|
||||
break;
|
||||
default:
|
||||
resetAnimation(boxId);
|
||||
$('#bottomanimationtext' + id).html('No animation');
|
||||
};
|
||||
};
|
||||
|
||||
function resetAnimation(boxId) {
|
||||
$(`${boxId} .bird`).removeClass('slowRotateBird floatingBird compressingBird');
|
||||
$(`${boxId} .beak_upper`).removeClass('upperSpeakingBird');
|
||||
$(`${boxId} .beak_lower`).removeClass('lowerSpeakingBird');
|
||||
$(`${boxId} .tail_top`).removeClass('topWaggingTail');
|
||||
$(`${boxId} .tail_middle`).removeClass('middleWaggingTail');
|
||||
$(`${boxId} .tail_bottom`).removeClass('bottomWaggingTail');
|
||||
$(`${boxId} .feather_top`).removeClass('topAttention');
|
||||
$(`${boxId} .feather_bottom`).removeClass('bottomAttention');
|
||||
$(`${boxId} .pupil`).removeClass('eyesFollow');
|
||||
};
|
||||
|
||||
function animationType1(boxId) {
|
||||
$(`${boxId} .bird`).addClass('slowRotateBird');
|
||||
};
|
||||
|
||||
function animationType2(boxId) {
|
||||
$(`${boxId} .bird`).addClass('floatingBird');
|
||||
};
|
||||
|
||||
function animationType3(boxId) {
|
||||
$(`${boxId} .bird`).addClass('compressingBird');
|
||||
};
|
||||
|
||||
function animationType4(boxId) {
|
||||
$(`${boxId} .beak_upper`).addClass('upperSpeakingBird');
|
||||
$(`${boxId} .beak_lower`).addClass('lowerSpeakingBird');
|
||||
};
|
||||
|
||||
function animationType5(boxId) {
|
||||
$(`${boxId} .tail_top`).addClass('topWaggingTail');
|
||||
$(`${boxId} .tail_middle`).addClass('middleWaggingTail');
|
||||
$(`${boxId} .tail_bottom`).addClass('bottomWaggingTail');
|
||||
};
|
||||
|
||||
function animationType6(boxId) {
|
||||
$(`${boxId} .feather_top`).addClass('topAttention');
|
||||
$(`${boxId} .feather_bottom`).addClass('bottomAttention');
|
||||
};
|
||||
|
||||
function animationType7(boxId) {
|
||||
$(`${boxId} .bird`).addClass('floatingBird');
|
||||
$(`${boxId} .beak_upper`).addClass('upperSpeakingBird');
|
||||
$(`${boxId} .beak_lower`).addClass('lowerSpeakingBird');
|
||||
$(`${boxId} .tail_top`).addClass('topWaggingTail');
|
||||
$(`${boxId} .tail_middle`).addClass('middleWaggingTail');
|
||||
$(`${boxId} .tail_bottom`).addClass('bottomWaggingTail');
|
||||
$(`${boxId} .feather_top`).addClass('topAttention');
|
||||
$(`${boxId} .feather_bottom`).addClass('bottomAttention');
|
||||
};
|
||||
|
||||
function animationType8(boxId) {
|
||||
basicEyes(boxId);
|
||||
$(`${boxId} .pupil`).addClass('eyesFollow');
|
||||
};
|
||||
|
||||
function printGeneration(genNo, id) {
|
||||
$('#generation' + id).html(genNo);
|
||||
};
|
||||
|
||||
function printMum(mum, id) {
|
||||
var print;
|
||||
if (mum == 0) {
|
||||
print = 'n/a'
|
||||
} else {
|
||||
print = mum;
|
||||
}
|
||||
$('#mum' + id).html(print);
|
||||
};
|
||||
|
||||
function printDad(dad, id) {
|
||||
var print;
|
||||
if (dad == 0) {
|
||||
print = 'n/a'
|
||||
} else {
|
||||
print = dad;
|
||||
};
|
||||
$('#dad' + id).html(print);
|
||||
};
|
548
client/assets/js/studio.js
Normal file
@ -0,0 +1,548 @@
|
||||
var colors = Object.values(allColors());
|
||||
|
||||
const defaultDNA = {
|
||||
"topFeatherColor": 23,
|
||||
"bodyFeatherColor": 54,
|
||||
"topBeakColor": 83,
|
||||
"bottomBeakColor": 73,
|
||||
"eyesShape": 0,
|
||||
"decorationPattern": 0,
|
||||
"decorationColor": 35,
|
||||
"decorationMidColor": 35,
|
||||
"decorationSmallColor": 35,
|
||||
"animation": 0
|
||||
};
|
||||
|
||||
$(document).ready( async () => {//when page is loaded, get latest instance of blockchain
|
||||
$('.colorscreen').show();
|
||||
$('.attributes').hide();
|
||||
setDefaultDna();
|
||||
await connectWallet();
|
||||
await onlyOwnerAccess();
|
||||
});
|
||||
|
||||
function setDefaultDna(){
|
||||
$('#dnaTopFeather').html(defaultDNA.topFeatherColor);
|
||||
$('#dnaBodyFeather').html(defaultDNA.bodyFeatherColor);
|
||||
$('#dnaTopBeak').html(defaultDNA.topBeakColor);
|
||||
$('#dnaBottomBeak').html(defaultDNA.bottomBeakColor);
|
||||
$('#dnaEyesShape').html(defaultDNA.eyesShape);
|
||||
$('#dnadecorationPattern').html(defaultDNA.decorationPattern);
|
||||
$('#dnaDecorationAtEyes').html(defaultDNA.decorationColor);
|
||||
$('#dnaDecorationMid').html(defaultDNA.decorationMidColor);
|
||||
$('#dnaDecorationSmall').html(defaultDNA.decorationSmallColor);
|
||||
$('#dnaAnimation').html(defaultDNA.animation);
|
||||
renderBird(defaultDNA);
|
||||
};
|
||||
|
||||
function renderBird(dna){
|
||||
topFeatherColor(colors[dna.topFeatherColor],dna.topFeatherColor);
|
||||
$('#topfeatherscolor').val(dna.topFeatherColor);
|
||||
bodyFeatherColor(colors[dna.bodyFeatherColor],dna.bodyFeatherColor);
|
||||
$('#bodyfeatherscolor').val(dna.bodyFeatherColor);
|
||||
topBeakColor(colors[dna.topBeakColor],dna.topBeakColor);
|
||||
$('#topbeakcolor').val(dna.topBeakColor);
|
||||
bottomBeakColor(colors[dna.bottomBeakColor],dna.bottomBeakColor);
|
||||
$('#bottombeakcolor').val(dna.bottomBeakColor);
|
||||
eyesVariation(dna.eyesShape);
|
||||
$('#eyesstyle').val(dna.eyesShape);
|
||||
decorationVariation(dna.decorationPattern);
|
||||
$('#decorationstyle').val(dna.decorationPattern);
|
||||
decorationMainColor(colors[dna.decorationColor],dna.decorationColor);
|
||||
$('#ateyescolor').val(dna.decorationColor);
|
||||
middleColor(colors[dna.decorationMidColor],dna.decorationMidColor);
|
||||
$('#middlecolor').val(dna.decorationMidColor);
|
||||
smallColor(colors[dna.decorationSmallColor],dna.decorationSmallColor);
|
||||
$('#smallcolor').val(dna.decorationSmallColor);
|
||||
animationVariation(dna.animation);
|
||||
$('#animationstyle').val(dna.animation);
|
||||
};
|
||||
|
||||
function getDna(){//used when bird created on blockchain
|
||||
var dna = '';
|
||||
dna += $('#dnaTopFeather').html();
|
||||
dna += $('#dnaBodyFeather').html();
|
||||
dna += $('#dnaTopBeak').html();
|
||||
dna += $('#dnaBottomBeak').html();
|
||||
dna += $('#dnaEyesShape').html();
|
||||
dna += $('#dnaDecorationPattern').html();
|
||||
dna += $('#dnaDecorationAtEye').html();
|
||||
dna += $('#dnaDecorationMid').html();
|
||||
dna += $('#dnaDecorationSmall').html();
|
||||
dna += $('#dnaAnimation').html();
|
||||
return dna;
|
||||
};
|
||||
|
||||
function setRandomDna(){
|
||||
var randomDna = {
|
||||
"topFeatherColor": Math.floor(Math.random()*90) + 10,// number from 10 to 99
|
||||
"bodyFeatherColor": Math.floor(Math.random()*90) + 10,// number from 10 to 99
|
||||
"topBeakColor": Math.floor(Math.random()*90) + 10,// number from 10 to 99
|
||||
"bottomBeakColor": Math.floor(Math.random()*90) + 10,// number from 10 to 99
|
||||
"eyesShape": Math.floor(Math.random()*8),// number from 0 to 7
|
||||
"decorationPattern": Math.floor(Math.random()*8),// number from 0 to 7
|
||||
"decorationColor": Math.floor(Math.random()*90) + 10,// number from 10 to 99
|
||||
"decorationMidColor": Math.floor(Math.random()*90) + 10,// number from 10 to 99
|
||||
"decorationSmallColor": Math.floor(Math.random()*90) + 10,// number from 10 to 99
|
||||
"animation": Math.floor(Math.random()*9)// number from 0 to 8
|
||||
};
|
||||
renderBird(randomDna);//this will always return 17 digits for the Dna of a bird.
|
||||
};
|
||||
|
||||
// Event listeners
|
||||
$('#colorsButton').click(()=>{
|
||||
$('.colorscreen').show();
|
||||
$('.attributes').hide();
|
||||
$('.bird').css('top', '15em');
|
||||
});
|
||||
|
||||
$('#attributesButton').click(()=>{
|
||||
$('.colorscreen').hide();
|
||||
$('.attributes').show();
|
||||
$('.bird').css('top', '25em');
|
||||
});
|
||||
|
||||
$('#topfeatherscolor').change(()=>{
|
||||
var colorVal = $('#topfeatherscolor').val();
|
||||
topFeatherColor(colors[colorVal],colorVal);
|
||||
});
|
||||
|
||||
$('#bodyfeatherscolor').change(()=>{
|
||||
var colorVal = $('#bodyfeatherscolor').val();
|
||||
bodyFeatherColor(colors[colorVal],colorVal);
|
||||
});
|
||||
|
||||
$('#topbeakcolor').change(()=>{
|
||||
var colorVal = $('#topbeakcolor').val();
|
||||
topBeakColor(colors[colorVal],colorVal);
|
||||
});
|
||||
|
||||
$('#bottombeakcolor').change(()=>{
|
||||
var colorVal = $('#bottombeakcolor').val();
|
||||
bottomBeakColor(colors[colorVal],colorVal);
|
||||
});
|
||||
|
||||
$('#eyesstyle').change(()=>{
|
||||
var shape = parseInt($('#eyesstyle').val());
|
||||
eyesVariation(shape);
|
||||
});
|
||||
|
||||
$('#decorationstyle').change(()=>{
|
||||
var shape = parseInt($('#decorationstyle').val());
|
||||
decorationVariation(shape);
|
||||
});
|
||||
|
||||
$('#ateyescolor').change(()=>{
|
||||
var colorVal = $('#ateyescolor').val();
|
||||
decorationMainColor(colors[colorVal],colorVal);
|
||||
});
|
||||
|
||||
$('#middlecolor').change(()=>{
|
||||
var colorVal = $('#middlecolor').val();
|
||||
middleColor(colors[colorVal],colorVal);
|
||||
});
|
||||
|
||||
$('#smallcolor').change(()=>{
|
||||
var colorVal = $('#smallcolor').val();
|
||||
smallColor(colors[colorVal],colorVal);
|
||||
});
|
||||
|
||||
$('#animationstyle').change(()=>{
|
||||
var variation = parseInt($('#animationstyle').val());
|
||||
animationVariation(variation);
|
||||
});
|
||||
|
||||
$('#randomizeButton').click(()=>{
|
||||
setRandomDna();
|
||||
});
|
||||
|
||||
$('#defaultButton').click(()=>{
|
||||
setDefaultDna();
|
||||
});
|
||||
|
||||
$('#createButton').click(()=>{
|
||||
createBird();
|
||||
});
|
||||
|
||||
function topFeatherColor(color,code) {
|
||||
$('.feather_top, .feather_bottom').css('background', '#' + color)
|
||||
//This changes the color of the bird
|
||||
$('#topfeatherstext').html('Code: '+ code)
|
||||
//This updates text of the badge above the slider
|
||||
$('#dnaTopFeather').html(code)
|
||||
//This updates the DNA that is displayed below the bird
|
||||
};
|
||||
|
||||
function bodyFeatherColor(color,code) {
|
||||
$('.bird_body_inner').css('background', '#' + color)
|
||||
$('#bodyfeatherstext').html('Code: '+ code)
|
||||
$('#dnaBodyFeather').html(code)
|
||||
};
|
||||
|
||||
function topBeakColor(color,code) {
|
||||
$('.beak_upper').css('background', '#' + color)
|
||||
$('#topbeaktext').html('Code: '+ code)
|
||||
$('#dnaTopBeak').html(code)
|
||||
};
|
||||
|
||||
function bottomBeakColor(color,code) {
|
||||
$('.beak_lower').css('background', '#' + color)
|
||||
$('#bottombeaktext').html('Code: '+ code)
|
||||
$('#dnaBottomBeak').html(code)
|
||||
};
|
||||
|
||||
function eyesVariation(num) {
|
||||
$('#dnaEyesShape').html(num)
|
||||
switch (num) {
|
||||
case 0:
|
||||
basicEyes();
|
||||
$('#eyesshapetext').html('Basic');
|
||||
break;
|
||||
case 1:
|
||||
basicEyes();
|
||||
$('#eyesshapetext').html('Chilled');
|
||||
eyesType1();
|
||||
break;
|
||||
case 2:
|
||||
basicEyes();
|
||||
$('#eyesshapetext').html('Up');
|
||||
eyesType2();
|
||||
break;
|
||||
case 3:
|
||||
basicEyes();
|
||||
$('#eyesshapetext').html('Right');
|
||||
eyesType3();
|
||||
break;
|
||||
case 4:
|
||||
basicEyes();
|
||||
$('#eyesshapetext').html('Left');
|
||||
eyesType4();
|
||||
break;
|
||||
case 5:
|
||||
basicEyes();
|
||||
$('#eyesshapetext').html('Dazzled');
|
||||
eyesType5();
|
||||
break;
|
||||
case 6:
|
||||
basicEyes();
|
||||
$('#eyesshapetext').html('Slit');
|
||||
eyesType6();
|
||||
break;
|
||||
case 7:
|
||||
basicEyes();
|
||||
$('#eyesshapetext').html('Mask');
|
||||
eyesType7();
|
||||
break;
|
||||
default:
|
||||
basicEyes();
|
||||
$('#eyesshapetext').html('Basic');
|
||||
};
|
||||
};
|
||||
|
||||
function basicEyes() {
|
||||
$('.eye').css({'border-top': 'none', 'border-bottom': 'none', 'border-left':
|
||||
'none', 'border-right': 'none', 'border': '0.9em black solid'});
|
||||
$('.eye_right .eyebrow').css({'left': '-1em', 'top': '-1.5em'});
|
||||
$('.eye_left .eyebrow').css({'left': '-3em', 'top': '-1.5em'});
|
||||
$('.eye_right .pupil').css({'left': '1.5em', 'top': '3em'});
|
||||
$('.eye_left .pupil').css({'left': '5em', 'top': '3em'});
|
||||
};
|
||||
|
||||
function eyesType1() {//Chilled
|
||||
$('.eye').css('border-top', '4em solid');
|
||||
$('.eye_right .eyebrow').css({'left': '-1em', 'top': '-4.5em'});
|
||||
$('.eye_left .eyebrow').css({'left': '-3em', 'top': '-4.5em'});
|
||||
$('.eye_right .pupil').css({'left': '1.5em', 'top': '1em'});
|
||||
$('.eye_left .pupil').css({'left': '5em', 'top': '1em'});
|
||||
};
|
||||
|
||||
function eyesType2() {//Up
|
||||
$('.eye').css('border-bottom', '4em solid');
|
||||
$('.eye_right .eyebrow').css({'left': '-1em', 'top': '-2em'});
|
||||
$('.eye_left .eyebrow').css({'left': '-3em', 'top': '-2em'});
|
||||
$('.eye_right .pupil').css({'left': '1.5em', 'top': '2em'});
|
||||
$('.eye_left .pupil').css({'left': '5em', 'top': '2em'});
|
||||
};
|
||||
|
||||
function eyesType3() {//Right
|
||||
$('.eye').css('border-left', '2.5em solid');
|
||||
$('.eye_right .eyebrow').css({'left': '-1em', 'top': '-1.5em'});
|
||||
$('.eye_left .eyebrow').css({'left': '-3em', 'top': '-1.5em'});
|
||||
$('.eye_right .pupil').css({'left': '5em', 'top': '3em'});
|
||||
$('.eye_left .pupil').css({'left': '5em', 'top': '3em'});
|
||||
};
|
||||
|
||||
function eyesType4() {//Left
|
||||
$('.eye').css('border-right', '2.5em solid');
|
||||
$('.eye_right .eyebrow').css({'left': '-1em', 'top': '-1.5em'});
|
||||
$('.eye_left .eyebrow').css({'left': '-3em', 'top': '-1.5em'});
|
||||
$('.eye_right .pupil').css({'left': '0em', 'top': '3em'});
|
||||
$('.eye_left .pupil').css({'left': '0em', 'top': '3em'});
|
||||
};
|
||||
|
||||
function eyesType5() {//Dazzled
|
||||
$('.eye').css({'border-top': '4em solid', 'border-bottom': '4em solid'});
|
||||
$('.eye_right .eyebrow').css({'left': '-1em', 'top': '-5.5em'});
|
||||
$('.eye_left .eyebrow').css({'left': '-3em', 'top': '-5.5em'});
|
||||
$('.eye_right .pupil').css({'left': '3em', 'top': '0em'});
|
||||
$('.eye_left .pupil').css({'left': '3em', 'top': '0em'});
|
||||
};
|
||||
|
||||
function eyesType6() {//Slit
|
||||
$('.eye').css({'border-top': '4em solid', 'border-left': '4em solid',
|
||||
'border-right': '4em solid'});
|
||||
$('.eye_right .eyebrow').css({'left': '-4em', 'top': '-5em'});
|
||||
$('.eye_left .eyebrow').css({'left': '-6em', 'top': '-5em'});
|
||||
$('.eye_right .pupil').css({'left': '-0.1em', 'top': '1em'});
|
||||
$('.eye_left .pupil').css({'left': '-0.1em', 'top': '1em'});
|
||||
};
|
||||
|
||||
function eyesType7() {//Mask
|
||||
$('.eye').css('border', '3em solid');
|
||||
$('.eye_right .eyebrow').css({'left': '-3em', 'top': '-5em'});
|
||||
$('.eye_left .eyebrow').css({'left': '-5em', 'top': '-5em'});
|
||||
$('.eye_right .pupil').css({'left': '1em', 'top': '1em'});
|
||||
$('.eye_left .pupil').css({'left': '1em', 'top': '1em'});
|
||||
};
|
||||
|
||||
function decorationVariation(num) {
|
||||
$('#dnaDecorationPattern').html(num)
|
||||
switch (num) {
|
||||
case 0:
|
||||
$('#decorationpatterntext').html('Basic');
|
||||
basicDecoration();
|
||||
break;
|
||||
case 1:
|
||||
basicDecoration();
|
||||
$('#decorationpatterntext').html('Large');
|
||||
decorationType1();
|
||||
break;
|
||||
case 2:
|
||||
basicDecoration();
|
||||
$('#decorationpatterntext').html('Max');
|
||||
decorationType2();
|
||||
break;
|
||||
case 3:
|
||||
basicDecoration();
|
||||
$('#decorationpatterntext').html('Eyes Only');
|
||||
decorationType3();
|
||||
break;
|
||||
case 4:
|
||||
basicDecoration();
|
||||
$('#decorationpatterntext').html('Back Only');
|
||||
decorationType4();
|
||||
break;
|
||||
case 5:
|
||||
basicDecoration();
|
||||
$('#decorationpatterntext').html('None');
|
||||
decorationType5();
|
||||
break;
|
||||
case 6:
|
||||
basicDecoration();
|
||||
$('#decorationpatterntext').html('Cross');
|
||||
decorationType6();
|
||||
break;
|
||||
case 7:
|
||||
basicDecoration();
|
||||
$('#decorationpatterntext').html('Cross & Eyes');
|
||||
decorationType7();
|
||||
break;
|
||||
default:
|
||||
basicDecoration();
|
||||
$('#decorationpatterntext').html('Basic');
|
||||
};
|
||||
};
|
||||
|
||||
function basicDecoration() {
|
||||
$('.bird_body .deco_1').css({'display': 'initial', 'transform':
|
||||
'rotate(-25deg) scaleY(1) translateX(0em) translateY(0em)'});
|
||||
$('.bird_body .deco_2').css({'display': 'initial', 'transform':
|
||||
'rotate(-15deg) scaleY(1) translateX(0em) translateY(0em)'});
|
||||
$('.bird_body .deco_3').css({'display': 'initial', 'transform':
|
||||
'rotate(-10deg) scaleY(1) translateY(0em)'});
|
||||
$('.bird_body .deco_4').css({'display': 'initial', 'transform':
|
||||
'rotate(-10deg) scaleY(1) translateY(0em)'});
|
||||
};
|
||||
|
||||
function decorationType1() {//Large
|
||||
$('.bird_body .deco_1').css('transform', 'rotate(-25deg) scaleY(2)');
|
||||
$('.bird_body .deco_2').css('transform', 'rotate(-15deg) scaleY(2)');
|
||||
$('.bird_body .deco_3').css('transform', 'rotate(-10deg) scaleY(2)');
|
||||
$('.bird_body .deco_4').css('transform', 'rotate(-10deg) scaleY(2)');
|
||||
};
|
||||
|
||||
function decorationType2() {//Max
|
||||
$('.bird_body .deco_1').css('transform', 'rotate(-25deg) scaleY(3) translateY(-2.5em)');
|
||||
$('.bird_body .deco_2').css('transform', 'rotate(-15deg) scaleY(3) translateY(-2.5em)');
|
||||
$('.bird_body .deco_3').css('transform', 'rotate(-10deg) scaleY(3) translateY(-2.5em)');
|
||||
$('.bird_body .deco_4').css('transform', 'rotate(-10deg) scaleY(3) translateY(-1.8em)');
|
||||
};
|
||||
|
||||
function decorationType3() {//Eyes Only
|
||||
$('.bird_body .deco_1').css('display', 'none');
|
||||
$('.bird_body .deco_2').css('display', 'none');
|
||||
$('.bird_body .deco_3').css('transform', 'rotate(-10deg) scaleY(3) translateY(-2.5em)');
|
||||
$('.bird_body .deco_4').css('transform', 'rotate(-10deg) scaleY(3) translateY(-1.8em)');
|
||||
};
|
||||
|
||||
function decorationType4() {//Back Only
|
||||
$('.bird_body .deco_1').css('transform', 'rotate(-25deg) scaleY(3) translateY(-2.5em)');
|
||||
$('.bird_body .deco_2').css('transform', 'rotate(-15deg) scaleY(3) translateY(-2.5em)');
|
||||
$('.bird_body .deco_3').css('display', 'none');
|
||||
$('.bird_body .deco_4').css('display', 'none');
|
||||
};
|
||||
|
||||
function decorationType5() {//None
|
||||
$('.bird_body .deco_1').css('display', 'none');
|
||||
$('.bird_body .deco_2').css('display', 'none');
|
||||
$('.bird_body .deco_3').css('display', 'none');
|
||||
$('.bird_body .deco_4').css('display', 'none');
|
||||
};
|
||||
|
||||
function decorationType6() {//Cross
|
||||
$('.bird_body .deco_1').css('transform',
|
||||
'rotate(90deg) scaleY(3) translateX(-9em) translateY(-0.5em)');
|
||||
$('.bird_body .deco_2').css('transform',
|
||||
'rotate(0deg) scaleY(3) translateX(-3.5em) translateY(-2.5em)');
|
||||
$('.bird_body .deco_3').css('display', 'none');
|
||||
$('.bird_body .deco_4').css('display', 'none');
|
||||
};
|
||||
|
||||
function decorationType7() {//Cross & Eyes
|
||||
$('.bird_body .deco_1').css('transform',
|
||||
'rotate(90deg) scaleY(3) translateX(-9em) translateY(-0.5em)');
|
||||
$('.bird_body .deco_2').css('transform',
|
||||
'rotate(0deg) scaleY(3) translateX(-3.5em) translateY(-2.5em)');
|
||||
$('.bird_body .deco_3').css('transform', 'rotate(-10deg) scaleY(2)');
|
||||
$('.bird_body .deco_4').css('transform', 'rotate(-10deg) scaleY(2)');
|
||||
};
|
||||
|
||||
function decorationMainColor(color,code) {
|
||||
$('.deco_3, .deco_4').css('background', '#' + color)
|
||||
$('#ateyestext').html('Code: '+ code)
|
||||
$('#dnaDecorationAtEye').html(code)
|
||||
};
|
||||
|
||||
function middleColor(color,code) {
|
||||
$('.deco_2').css('background', '#' + color)
|
||||
$('#middletext').html('Code: '+ code)
|
||||
$('#dnaDecorationMid').html(code)
|
||||
};
|
||||
|
||||
function smallColor(color,code) {
|
||||
$('.deco_1').css('background', '#' + color)
|
||||
$('#smalltext').html('Code: '+ code)
|
||||
$('#dnaDecorationSmall').html(code)
|
||||
};
|
||||
|
||||
function animationVariation(num) {
|
||||
$('#dnaAnimation').html(num)
|
||||
switch (num) {
|
||||
case 0:
|
||||
resetAnimation();
|
||||
$('#animationtext').html('None');
|
||||
break;
|
||||
case 1:
|
||||
resetAnimation();
|
||||
$('#animationtext').html('Kick');
|
||||
animationType1();
|
||||
break;
|
||||
case 2:
|
||||
resetAnimation();
|
||||
$('#animationtext').html('Float');
|
||||
animationType2();
|
||||
break;
|
||||
case 3:
|
||||
resetAnimation();
|
||||
$('#animationtext').html('Compress');
|
||||
animationType3();
|
||||
break;
|
||||
case 4:
|
||||
resetAnimation();
|
||||
$('#animationtext').html('Speak');
|
||||
animationType4();
|
||||
break;
|
||||
case 5:
|
||||
resetAnimation();
|
||||
$('#animationtext').html('Wag');
|
||||
animationType5();
|
||||
break;
|
||||
case 6:
|
||||
resetAnimation();
|
||||
$('#animationtext').html('Attention');
|
||||
animationType6();
|
||||
break;
|
||||
case 7:
|
||||
resetAnimation();
|
||||
$('#animationtext').html('Combi');
|
||||
animationType7();
|
||||
break;
|
||||
case 8:
|
||||
resetAnimation();
|
||||
$('#animationtext').html('Follow');
|
||||
animationType8();
|
||||
break;
|
||||
default:
|
||||
resetAnimation();
|
||||
$('#animationtext').html('None');
|
||||
};
|
||||
};
|
||||
|
||||
function resetAnimation() {
|
||||
$('*').removeClass('slowRotateBird floatingBird compressingBird upperSpeakingBird');
|
||||
$('*').removeClass('lowerSpeakingBird topWaggingTail middleWaggingTail');
|
||||
$('*').removeClass('bottomWaggingTail topAttention bottomAttention');
|
||||
document.onmousemove = function(){};
|
||||
};
|
||||
|
||||
function animationType1() {
|
||||
$('.bird').addClass('slowRotateBird');
|
||||
};
|
||||
|
||||
function animationType2() {
|
||||
$('.bird').addClass('floatingBird');
|
||||
};
|
||||
|
||||
function animationType3() {
|
||||
$('.bird').addClass('compressingBird');
|
||||
};
|
||||
|
||||
function animationType4() {
|
||||
$('.beak_upper').addClass('upperSpeakingBird');
|
||||
$('.beak_lower').addClass('lowerSpeakingBird');
|
||||
};
|
||||
|
||||
function animationType5() {
|
||||
$('.tail_top').addClass('topWaggingTail');
|
||||
$('.tail_middle').addClass('middleWaggingTail');
|
||||
$('.tail_bottom').addClass('bottomWaggingTail');
|
||||
};
|
||||
|
||||
function animationType6() {
|
||||
$('.feather_top').addClass('topAttention');
|
||||
$('.feather_bottom').addClass('bottomAttention');
|
||||
};
|
||||
|
||||
function animationType7() {
|
||||
$('.bird').addClass('floatingBird');
|
||||
$('.beak_upper').addClass('upperSpeakingBird');
|
||||
$('.beak_lower').addClass('lowerSpeakingBird');
|
||||
$('.tail_top').addClass('topWaggingTail');
|
||||
$('.tail_middle').addClass('middleWaggingTail');
|
||||
$('.tail_bottom').addClass('bottomWaggingTail');
|
||||
$('.feather_top').addClass('topAttention');
|
||||
$('.feather_bottom').addClass('bottomAttention');
|
||||
};
|
||||
|
||||
function animationType8() {
|
||||
basicEyes();
|
||||
var eyeballs = document.getElementsByClassName("pupil");
|
||||
document.onmousemove = function(event) {
|
||||
var x = event.clientX * 65 / window.innerWidth + "%";
|
||||
var y = event.clientY * 65 / window.innerHeight + "%";
|
||||
for (let i = 0; i < eyeballs.length; i++) {
|
||||
eyeballs[i].style.left = x;
|
||||
eyeballs[i].style.top = y;
|
||||
};
|
||||
};
|
||||
};
|
57
client/assets/js/web3.min.js
vendored
Normal file
BIN
client/assets/media/Bird.jpg
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
client/assets/media/Birdy.jpg
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
client/assets/media/Breed.gif
Normal file
After Width: | Height: | Size: 106 KiB |
BIN
client/assets/media/Coins.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
client/assets/media/Hearts.png
Normal file
After Width: | Height: | Size: 432 KiB |
BIN
client/assets/media/favicons/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
client/assets/media/favicons/android-chrome-512x512.png
Normal file
After Width: | Height: | Size: 201 KiB |
BIN
client/assets/media/favicons/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
client/assets/media/favicons/favicon-16x16.png
Normal file
After Width: | Height: | Size: 723 B |
BIN
client/assets/media/favicons/favicon-32x32.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
client/assets/media/favicons/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
1
client/assets/media/favicons/site.webmanifest
Normal file
@ -0,0 +1 @@
|
||||
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
113
client/breeding.html
Normal file
@ -0,0 +1,113 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Breeding - Angry Birds on the Block</title>
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180"
|
||||
href="assets/media/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32"
|
||||
href="assets/media/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16"
|
||||
href="assets/media/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="assets/media/favicons/site.webmanifest">
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/animations.css">
|
||||
<link rel="stylesheet" href="assets/css/bird.css">
|
||||
<link rel="stylesheet" href="assets/css/styles.css">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins&display=swap">
|
||||
<script type="text/javascript" src="assets/js/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript" src="assets/js/web3.min.js"></script>
|
||||
<script type="text/javascript" src="assets/js/abi.js"></script>
|
||||
<script type="text/javascript" src="assets/bootstrap/js/popper.js"></script>
|
||||
<script type="text/javascript" src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container p-5">
|
||||
|
||||
<!-- Navbar -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#"><img id="logo" height="50"
|
||||
src="assets/media/Birdy.jpg"> Crypto Birdies </a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse"
|
||||
data-target="#navbarTogglerDemo02" aria-controls="navbarTogglerDemo02"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarTogglerDemo02">
|
||||
<ul class="navbar-nav mr-auto mt-2 mt-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./index.html">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./catalog.html">Catalog</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./breeding.html">Breeding</a>
|
||||
</li>
|
||||
<li id="designStudio" class="nav-item">
|
||||
<a class="nav-link" href="./studio.html">Design Studio</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./market.html">Market Place</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Allows owner to pause execution of buyBird() and withdrawFunds() for maintenance only -->
|
||||
<button style="display: none" id="pauseButton" class="btn btn-danger my-2 my-sm-0" type="submit"></button>
|
||||
</nav><br>
|
||||
|
||||
<!-- Headlines -->
|
||||
<div align="center">
|
||||
<div style="display: none" class="alert alert-danger" role="alert" id="pauseMessage">
|
||||
Contract paused for maintenance! Buying birds and withdrawing funds is temporarily unavailable.
|
||||
Normal operations will be restored as soon as possible! Please check in soon!
|
||||
</div>
|
||||
<h1 class="c-white"><b>Breed your own birdies!</b></h1>
|
||||
<p id="insufficient" class="c-white">Choose the parents for your birdy once you own at least two adults</p>
|
||||
<div class="alert alert-success" role="alert" id="birdCreation"
|
||||
style="display: none"></div><br>
|
||||
</div><br>
|
||||
|
||||
<!-- Parents, Child & Buttons -->
|
||||
<div id="dameDisplay"></div>
|
||||
<div id="sireDisplay"></div>
|
||||
<div id="childDisplay">
|
||||
<img style ="display: none" class="evolvingHeart" src="assets/media/Hearts.png">
|
||||
</div>
|
||||
<button id="dameButton" type="button" class="btn btn-primary">Change Dame</button>
|
||||
<button id="sireButton" type="button" class="btn btn-primary">Change Sire</button>
|
||||
<button id="breedButton" type="button" class="btn btn-danger">Breed a new bird!</button>
|
||||
<button id="breedAgainButton" type="button" class="btn btn-danger">Breed again!</button>
|
||||
<button id="swapButton" type="button" class="btn btn-primary"
|
||||
style="display: none">Swap Dame and Sire</button><br>
|
||||
|
||||
<!-- Modal box -->
|
||||
<div class="modal" id="birdSelection" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">My birds</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Select one of your birds.</p>
|
||||
<div class="row"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" data-dismiss="modal">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer align="center" id="breedFooter">
|
||||
Written by <a href="mailto:the.rainmaker@mail.com">The Rainmaker</a>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
<script src="assets/js/blockchain.js"></script>
|
||||
<script src="assets/js/colors.js"></script>
|
||||
<script src="assets/js/breeding.js"></script>
|
||||
<script src="assets/js/rendering.js"></script>
|
||||
</html>
|
93
client/catalog.html
Normal file
@ -0,0 +1,93 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Catalog - Angry Birds on the Block</title>
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180"
|
||||
href="assets/media/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32"
|
||||
href="assets/media/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16"
|
||||
href="assets/media/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="assets/media/favicons/site.webmanifest">
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/animations.css">
|
||||
<link rel="stylesheet" href="assets/css/bird.css">
|
||||
<link rel="stylesheet" href="assets/css/styles.css">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins&display=swap">
|
||||
<script type="text/javascript" src="assets/js/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript" src="assets/js/web3.min.js"></script>
|
||||
<script type="text/javascript" src="assets/js/abi.js"></script>
|
||||
<script type="text/javascript" src="assets/bootstrap/js/popper.js"></script>
|
||||
<script type="text/javascript" src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container p-5">
|
||||
|
||||
<!-- Navbar -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#"><img id="logo" height="50"
|
||||
src="assets/media/Birdy.jpg"> Crypto Birdies </a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse"
|
||||
data-target="#navbarTogglerDemo02" aria-controls="navbarTogglerDemo02"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarTogglerDemo02">
|
||||
<ul class="navbar-nav mr-auto mt-2 mt-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./index.html">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./catalog.html">Catalog</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./breeding.html">Breeding</a>
|
||||
</li>
|
||||
<li id="designStudio" class="nav-item">
|
||||
<a class="nav-link" href="./studio.html">Design Studio</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./market.html">Market Place</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Allows owner to pause execution of buyBird() and withdrawFunds() for maintenance only -->
|
||||
<button style="display: none" id="pauseButton" class="btn btn-danger my-2 my-sm-0" type="submit"></button>
|
||||
</nav><br>
|
||||
|
||||
<!-- Headlines & Receipt -->
|
||||
<div align="center">
|
||||
<div style="display: none" class="alert alert-danger" role="alert" id="pauseMessage">
|
||||
Contract paused for maintenance! Buying birds and withdrawing funds is temporarily unavailable.
|
||||
Normal operations will be restored as soon as possible! Please check in soon!
|
||||
</div>
|
||||
<h1 class="c-white"><b>My Bird Collection</b></h1>
|
||||
<p>Once you own birds, they will be displayed here</p>
|
||||
<p>Make money by creating offers for your birds! -
|
||||
Active offers will be transferred to the Market Place</p>
|
||||
<div id="withdrawBox" class="alert alert-success" role="alert">
|
||||
<span id="fundsAvailable"></span>
|
||||
<button id="withdrawButton" class="btn btn-success" type="button"
|
||||
id="button-addon2">Withdraw All
|
||||
</button>
|
||||
</div>
|
||||
<div class="alert alert-success" role="alert" id="offerCreated"
|
||||
style="display: none"></div>
|
||||
</div>
|
||||
|
||||
<!-- Bird Boxes -->
|
||||
<div class="row"></div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer align="center">
|
||||
Written by <a href="mailto:the.rainmaker@mail.com">The Rainmaker</a>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
<script src="assets/js/blockchain.js"></script>
|
||||
<script src="assets/js/colors.js"></script>
|
||||
<script src="assets/js/rendering.js"></script>
|
||||
<script src="assets/js/catalog.js"></script>
|
||||
</html>
|
107
client/index.html
Normal file
@ -0,0 +1,107 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Crypto Birdies</title>
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180"
|
||||
href="assets/media/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32"
|
||||
href="assets/media/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16"
|
||||
href="assets/media/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="assets/media/favicons/site.webmanifest">
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/styles.css">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins&display=swap">
|
||||
<script type="text/javascript" src="assets/js/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript" src="assets/js/web3.min.js"></script>
|
||||
<script type="text/javascript" src="assets/js/abi.js"></script>
|
||||
<script type="text/javascript" src="assets/bootstrap/js/popper.js"></script>
|
||||
<script type="text/javascript" src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container p-5">
|
||||
|
||||
<!-- Navbar -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#"><img id="logo" height="50"
|
||||
src="assets/media/Birdy.jpg"> Crypto Birdies </a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse"
|
||||
data-target="#navbarTogglerDemo02" aria-controls="navbarTogglerDemo02"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarTogglerDemo02">
|
||||
<ul class="navbar-nav mr-auto mt-2 mt-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./index.html">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./catalog.html">Catalog</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./breeding.html">Breeding</a>
|
||||
</li>
|
||||
<li id="designStudio" class="nav-item">
|
||||
<a class="nav-link" href="./studio.html">Design Studio</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./market.html">Market Place</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Allows owner to pause execution of buyBird() and withdrawFunds() for maintenance only -->
|
||||
<button style="display: none" id="pauseButton" class="btn btn-danger my-2 my-sm-0" type="submit"></button>
|
||||
</nav><br>
|
||||
|
||||
<!-- Feature Cards -->
|
||||
<div style="display: none" class="alert alert-danger" role="alert" id="pauseMessage">
|
||||
Contract paused for maintenance! Buying birds and withdrawing funds is temporarily unavailable.
|
||||
Normal operations will be restored as soon as possible! Please check in soon!
|
||||
</div>
|
||||
<div class="card-deck">
|
||||
<div class="card">
|
||||
<img src="assets/media/Bird.jpg" class="card-img-top" alt="collections">
|
||||
<div class="card-body card-special">
|
||||
<h5 class="card-title">Collect & earn rewards</h5>
|
||||
<p class="card-text">Collect all types of birds with unique attributes!
|
||||
Earn special birds through breeding.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<img src="assets/media/Breed.gif" class="card-img-top" alt="breeding">
|
||||
<div class="card-body card-special">
|
||||
<h5 class="card-title">Breed adorable birds & unlock uncommon traits</h5>
|
||||
<p class="card-text">Create new birds by pairing two parents.
|
||||
Fuse them to get the rarest birds!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<img src="assets/media/Coins.png" class="card-img-top" alt="crypto-currency">
|
||||
<div class="card-body card-special">
|
||||
<h5 class="card-title">Trade Birds</h5>
|
||||
<p class="card-text">Buy or sell birds in a market place using crypto currency!
|
||||
You can find the most exotic specimens here.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div><br>
|
||||
|
||||
<!-- Action Card -->
|
||||
<div topCard class="card border-dark mb-3 justify-content-center topCard"
|
||||
style="max-width: 18rem;">
|
||||
<div class="card-body text-success">
|
||||
<h5 id="cardTitle">Collect! Breed! Trade!</h5>
|
||||
<button id="cardButton" class="btn btn-dark my-2 my-sm-0" type="submit"
|
||||
onclick="window.location.href='./market.html';">Get your own Birds</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer align="center">
|
||||
Written by <a href="mailto:the.rainmaker@mail.com">The Rainmaker</a>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
<script src="assets/js/blockchain.js"></script>
|
||||
<script src="assets/js/index.js"></script>
|
||||
</html>
|
95
client/market.html
Normal file
@ -0,0 +1,95 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Market Place - Angry Birds on the Block</title>
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180"
|
||||
href="assets/media/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32"
|
||||
href="assets/media/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16"
|
||||
href="assets/media/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="assets/media/favicons/site.webmanifest">
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/animations.css">
|
||||
<link rel="stylesheet" href="assets/css/bird.css">
|
||||
<link rel="stylesheet" href="assets/css/styles.css">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins&display=swap">
|
||||
<script type="text/javascript" src="assets/js/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript" src="assets/js/web3.min.js"></script>
|
||||
<script type="text/javascript" src="assets/js/abi.js"></script>
|
||||
<script type="text/javascript" src="assets/bootstrap/js/popper.js"></script>
|
||||
<script type="text/javascript" src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container p-5">
|
||||
|
||||
<!-- Navbar -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#"><img id="logo" height="50"
|
||||
src="assets/media/Birdy.jpg"> Crypto Birdies </a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse"
|
||||
data-target="#navbarTogglerDemo02" aria-controls="navbarTogglerDemo02" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarTogglerDemo02">
|
||||
<ul class="navbar-nav mr-auto mt-2 mt-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./index.html">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./catalog.html">Catalog</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./breeding.html">Breeding</a>
|
||||
</li>
|
||||
<li id="designStudio" class="nav-item">
|
||||
<a class="nav-link" href="./studio.html">Design Studio</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./market.html">Market Place</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Allows owner to pause execution of buyBird() and withdrawFunds() for maintenance only -->
|
||||
<button style="display: none" id="pauseButton" class="btn btn-danger my-2 my-sm-0" type="submit"></button>
|
||||
</nav><br>
|
||||
|
||||
<!-- Headlines & Receipt -->
|
||||
<div align="center">
|
||||
<div style="display: none" class="alert alert-danger" role="alert" id="pauseMessage">
|
||||
Contract paused for maintenance! Buying birds and withdrawing funds is temporarily unavailable.
|
||||
Normal operations will be restored as soon as possible! Please check in soon!
|
||||
</div>
|
||||
<h1 class="c-white"><b>My Offers</b></h1>
|
||||
<p class="c-white">Cancelling an offer will return the bird to your catalog</p>
|
||||
<div class="alert alert-success" role="alert" id="offerRemoved"
|
||||
style="display: none"></div>
|
||||
</div>
|
||||
|
||||
<!-- Offer Boxes -->
|
||||
<div class="myOffers"></div><hr>
|
||||
|
||||
<!-- Headlines & Receipt -->
|
||||
<div align="center">
|
||||
<h1 class="c-white"><b>Offers of other Players</b></h1>
|
||||
<p class="c-white">Buy Rare and Unusual Birds!</p>
|
||||
<div class="alert alert-success" role="alert" id="birdPurchased"
|
||||
style="display: none"></div>
|
||||
</div>
|
||||
|
||||
<!-- Market Boxes -->
|
||||
<div class="marketOffers"></div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer align="center">
|
||||
Written by <a href="mailto:the.rainmaker@mail.com">The Rainmaker</a>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
<script src="assets/js/blockchain.js"></script>
|
||||
<script src="assets/js/colors.js"></script>
|
||||
<script src="assets/js/rendering.js"></script>
|
||||
<script src="assets/js/market.js"></script>
|
||||
</html>
|
214
client/studio.html
Normal file
@ -0,0 +1,214 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Design Studio - Angry Birds on the Block</title>
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180"
|
||||
href="assets/media/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32"
|
||||
href="assets/media/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16"
|
||||
href="assets/media/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="assets/media/favicons/site.webmanifest">
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/animations.css">
|
||||
<link rel="stylesheet" href="assets/css/bird.css">
|
||||
<link rel="stylesheet" href="assets/css/styles.css">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins&display=swap">
|
||||
<script type="text/javascript" src="assets/js/jquery-3.5.1.min.js"></script>
|
||||
<script type="text/javascript" src="assets/js/web3.min.js"></script>
|
||||
<script type="text/javascript" src="assets/js/abi.js"></script>
|
||||
<script type="text/javascript" src="assets/bootstrap/js/popper.js"></script>
|
||||
<script type="text/javascript" src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container p-5">
|
||||
|
||||
<!-- Navbar -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#"><img id="logo" height="50"
|
||||
src="assets/media/Birdy.jpg"> Crypto Birdies </a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse"
|
||||
data-target="#navbarTogglerDemo02" aria-controls="navbarTogglerDemo02"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarTogglerDemo02">
|
||||
<ul class="navbar-nav mr-auto mt-2 mt-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./index.html">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./catalog.html">Catalog</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./breeding.html">Breeding</a>
|
||||
</li>
|
||||
<li id="designStudio" class="nav-item">
|
||||
<a class="nav-link" href="#">Design Studio</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="./market.html">Market Place</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Allows owner to pause execution of buyBird() and withdrawFunds() for maintenance only -->
|
||||
<button style="display: none" id="pauseButton" class="btn btn-danger my-2 my-sm-0" type="submit"></button>
|
||||
</nav><br>
|
||||
|
||||
<!-- Headlines -->
|
||||
<div align="center">
|
||||
<div style="display: none" class="alert alert-danger" role="alert" id="pauseMessage">
|
||||
Contract paused for maintenance! Buying birds and withdrawing funds is temporarily unavailable.
|
||||
Normal operations will be restored as soon as possible! Please check in soon!
|
||||
</div>
|
||||
<h1 class="c-white"><b>Design Studio</b></h1>
|
||||
<p class="c-white">Create Your Own Bird</p>
|
||||
<div class="alert alert-success" role="alert" id="birdCreation"
|
||||
style="display: none"></div>
|
||||
</div>
|
||||
|
||||
<!-- BirdBox -->
|
||||
<div class="row">
|
||||
<div class="col-lg-4 birdBox m-2 light-b-shadow">
|
||||
<div class="bird">
|
||||
<div class="tail">
|
||||
<div class="tail_top"></div>
|
||||
<div class="tail_middle"></div>
|
||||
<div class="tail_bottom"></div>
|
||||
</div>
|
||||
<div class="feather">
|
||||
<div class="feather_top"></div>
|
||||
<div class="feather_bottom"></div>
|
||||
</div>
|
||||
<div class="bird_body">
|
||||
<div class="bird_body bird_body_inner"></div>
|
||||
<div class="deco_1"></div>
|
||||
<div class="deco_2"></div>
|
||||
<div class="deco_3"></div>
|
||||
<div class="deco_4"></div>
|
||||
</div>
|
||||
<div class="belly"></div>
|
||||
<div class="face">
|
||||
<div class="eye eye_right">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="eye eye_left">
|
||||
<div class="eyebrow"></div>
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="beak">
|
||||
<div class="beak_upper"></div>
|
||||
<div class="beak_lower"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<div class="dnaDiv">
|
||||
<b>
|
||||
DNA:
|
||||
<span id="dnaTopFeather"></span>
|
||||
<span id="dnaBodyFeather"></span>
|
||||
<span id="dnaTopBeak"></span>
|
||||
<span id="dnaBottomBeak"></span>
|
||||
<span id="dnaEyesShape"></span>
|
||||
<span id="dnaDecorationPattern"></span>
|
||||
<span id="dnaDecorationAtEye"></span>
|
||||
<span id="dnaDecorationMid"></span>
|
||||
<span id="dnaDecorationSmall"></span>
|
||||
<span id="dnaAnimation"></span>
|
||||
</b>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Color & Feature Box -->
|
||||
<div class="col-lg-7 birdAttributes m-2 light-b-shadow ">
|
||||
<button type="button" id="colorsButton"
|
||||
class="m-2 btn btn-primary light-b-shadow"><b>Colors</b></button>
|
||||
<button type="button" id="attributesButton"
|
||||
class="m-2 btn btn-primary light-b-shadow"><b>Attributes</b></button>
|
||||
<div class="form-group">
|
||||
<div class="colorscreen"><br><br>
|
||||
<label for="formControlRange"><b>Top Feathers</b>
|
||||
<span class="badge badge-dark ml-2" id="topfeatherstext"></span></label>
|
||||
<input type="range" min="10" max="99" class="form-control-range"
|
||||
id="topfeatherscolor">
|
||||
<label for="formControlRange"><b>Body Feathers</b><span
|
||||
class="badge badge-dark ml-2" id="bodyfeatherstext"></span></label>
|
||||
<input type="range" min="10" max="99" class="form-control-range"
|
||||
id="bodyfeatherscolor">
|
||||
<label for="formControlRange"><b>Beak - Top</b><span
|
||||
class="badge badge-dark ml-2" id="topbeaktext"></span></label>
|
||||
<input type="range" min="10" max="99" class="form-control-range"
|
||||
id="topbeakcolor">
|
||||
<label for="formControlRange"><b>Beak - Bottom</b><span
|
||||
class="badge badge-dark ml-2" id="bottombeaktext"></span></label>
|
||||
<input type="range" min="10" max="99" class="form-control-range"
|
||||
id="bottombeakcolor">
|
||||
</div>
|
||||
<div class="attributes"><br>
|
||||
<label for="formControlRange"><b>Eyes Shape</b><span
|
||||
class="badge badge-dark ml-2" id="eyesshapetext"></span></label>
|
||||
<input type="range" min="0" max="7" class="form-control-range"
|
||||
id="eyesstyle">
|
||||
<label for="formControlRange"><b>Decoration Pattern</b><span
|
||||
class="badge badge-dark ml-2" id="decorationpatterntext"></span></label>
|
||||
<input type="range" min="0" max="7" class="form-control-range"
|
||||
id="decorationstyle">
|
||||
<label for="formControlRange"><b>Decoration</b></label><br>
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="formControlRange"><b>At Eyes</b>
|
||||
<span class="badge badge-dark ml-2" id="ateyestext"></span></label>
|
||||
<input type="range" min="10" max="99" class="form-control-range"
|
||||
id="ateyescolor">
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="formControlRange"><b>Middle</b>
|
||||
<span class="badge badge-dark ml-2" id="middletext"></span></label>
|
||||
<input type="range" min="10" max="99" class="form-control-range"
|
||||
id="middlecolor">
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label for="formControlRange"><b>Small</b>
|
||||
<span class="badge badge-dark ml-2" id="smalltext"></span></label>
|
||||
<input type="range" min="10" max="99" class="form-control-range"
|
||||
id="smallcolor">
|
||||
</div>
|
||||
</div>
|
||||
<label for="formControlRange"><b>Animation</b><span
|
||||
class="badge badge-dark ml-2" id="animationtext"></span></label>
|
||||
<input type="range" min="0" max="8" class="form-control-range"
|
||||
id="animationstyle">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<div class="btn-group float-left">
|
||||
<button type="button" id="randomizeButton"
|
||||
class="btn btn-primary mr-5 tsp-1 m-1 light-b-shadow">
|
||||
<b>Random Bird</b></button>
|
||||
<button type="button" id="defaultButton"
|
||||
class="btn btn-primary mr-5 tsp-1 m-1 light-b-shadow">
|
||||
<b>Default Bird</b></button>
|
||||
</div>
|
||||
<div class="btn-group float-right">
|
||||
<button type="button" id="createButton"
|
||||
class="btn btn-success mr-5 tsp-1 m-1 light-b-shadow">
|
||||
<b>Create Bird</b></button>
|
||||
</div><br>
|
||||
</div>
|
||||
</div><br>
|
||||
<footer align="center">
|
||||
Written by <a href="mailto:the.rainmaker@mail.com">The Rainmaker</a>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
<script src="assets/js/blockchain.js"></script>
|
||||
<script src="assets/js/colors.js"></script>
|
||||
<script src="assets/js/studio.js"></script>
|
||||
</html>
|
309
contracts/CryptoBirdies.sol
Normal file
@ -0,0 +1,309 @@
|
||||
pragma solidity ^0.5.12;
|
||||
|
||||
import "./Ownable.sol";
|
||||
import "./Destroyable.sol";
|
||||
import "./IERC165.sol";
|
||||
import "./IERC721.sol";
|
||||
import "./IERC721Receiver.sol";
|
||||
import "./SafeMath.sol";
|
||||
|
||||
contract CryptoBirdies is Ownable, Destroyable, IERC165, IERC721 {
|
||||
|
||||
using SafeMath for uint256;
|
||||
|
||||
uint256 public constant maxGen0Birds = 10;//allow a maximum of 10 Gen0 birds
|
||||
uint256 public gen0Counter = 0;
|
||||
|
||||
bytes4 internal constant _ERC721Checksum = bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
|
||||
//checksum used to determine if a receiving contract is able to handle ERC721 tokens
|
||||
bytes4 private constant _InterfaceIdERC721 = 0x80ac58cd;
|
||||
//checksum of function headers that are required in standard interface
|
||||
bytes4 private constant _InterfaceIdERC165 = 0x01ffc9a7;
|
||||
//checksum of function headers that are required in standard interface
|
||||
|
||||
string private _name;
|
||||
string private _symbol;
|
||||
|
||||
struct Bird {
|
||||
uint256 genes;
|
||||
uint64 birthTime;
|
||||
uint32 mumId;
|
||||
uint32 dadId;
|
||||
uint16 generation;
|
||||
}
|
||||
|
||||
Bird[] birdies;
|
||||
|
||||
mapping(uint256 => address) public birdOwner;
|
||||
mapping(address => uint256) ownsNumberOfTokens;
|
||||
mapping(uint256 => address) public approvalOneBird;//which bird is approved to be transfered
|
||||
//by an address other than the owner
|
||||
mapping(address => mapping (address => bool)) private _operatorApprovals;
|
||||
//approval to handle all tokens of an address by another
|
||||
//_operatorApprovals[owneraddress][operatoraddress] = true/false;
|
||||
|
||||
//ERC721 events are not defined here as they are inherited from IERC721
|
||||
event Birth(address owner, uint256 birdId, uint256 mumId, uint256 dadId, uint256 genes);
|
||||
|
||||
constructor(string memory name, string memory symbol) public {
|
||||
_name = name;
|
||||
_symbol = symbol;
|
||||
_createBird(0, 0, 0, uint256(-1), address(0));
|
||||
//Bird 0 doesn't do anything, but it exists in the mappings and arrays to avoid issues in the market place
|
||||
}
|
||||
|
||||
function getContractOwner() external view returns (address contractowner) {
|
||||
return _owner;
|
||||
}
|
||||
|
||||
function breed(uint256 _dadId, uint256 _mumId) external returns (uint256){
|
||||
require(birdOwner[_dadId] == msg.sender && birdOwner[_mumId] == msg.sender,
|
||||
"You can't breed what you don't own");
|
||||
|
||||
(uint256 _dadDna,,,, uint256 _dadGeneration) = getBird(_dadId);//discarding redundant data here
|
||||
(uint256 _mumDna,,,, uint256 _mumGeneration) = getBird(_mumId);//discarding redundant data here
|
||||
uint256 _newDna = _mixDna(
|
||||
_dadDna,
|
||||
_mumDna,
|
||||
uint8(now % 255),//This will return a number 0-255. e.g. 10111000
|
||||
uint8(now % 1),//seventeenth digit
|
||||
uint8(now % 7),//number to select random pair.
|
||||
uint8((now % 89) + 10)//value of random pair, making sure there's no leading '0'.
|
||||
);
|
||||
uint256 _newGeneration;
|
||||
|
||||
if (_dadGeneration <= _mumGeneration) {
|
||||
_newGeneration = _dadGeneration;
|
||||
} else {
|
||||
_newGeneration = _mumGeneration;
|
||||
}
|
||||
_newGeneration = SafeMath.add(_newGeneration, 1);
|
||||
return _createBird(_mumId, _dadId, _newGeneration, _newDna, msg.sender);
|
||||
}
|
||||
|
||||
function supportsInterface(bytes4 _interfaceId) external view returns (bool) {
|
||||
return (_interfaceId == _InterfaceIdERC721 || _interfaceId == _InterfaceIdERC165);
|
||||
}
|
||||
|
||||
function createBirdGen0(uint256 genes) public onlyOwner returns (uint256) {
|
||||
require(gen0Counter < maxGen0Birds, "Maximum number of Birds is reached. No new birds allowed!");
|
||||
gen0Counter = SafeMath.add(gen0Counter, 1);
|
||||
return _createBird(0, 0, 0, genes, msg.sender);
|
||||
}
|
||||
|
||||
function _createBird(
|
||||
uint256 _mumId,
|
||||
uint256 _dadId,
|
||||
uint256 _generation,
|
||||
uint256 _genes,
|
||||
address _owner
|
||||
) internal returns (uint256) {
|
||||
Bird memory _bird = Bird({
|
||||
genes: _genes,
|
||||
birthTime: uint64(now),
|
||||
mumId: uint32(_mumId), //easier to input 256 and later convert to 32.
|
||||
dadId: uint32(_dadId),
|
||||
generation: uint16(_generation)
|
||||
});
|
||||
birdies.push(_bird);
|
||||
uint256 newBirdId = SafeMath.sub(birdies.length, 1);//want to start with zero.
|
||||
_transfer(address(0), _owner, newBirdId);//transfer from nowhere. Creation event.
|
||||
emit Birth(_owner, newBirdId, _mumId, _dadId, _genes);
|
||||
return newBirdId;
|
||||
}
|
||||
|
||||
function getBird(uint256 tokenId) public view returns (
|
||||
uint256 genes,
|
||||
uint256 birthTime,
|
||||
uint256 mumId,
|
||||
uint256 dadId,
|
||||
uint256 generation) //code looks cleaner when the params appear here vs. in the return statement.
|
||||
{
|
||||
require(tokenId < birdies.length, "Token ID doesn't exist.");
|
||||
Bird storage bird = birdies[tokenId];//saves space over using memory, which would make a copy
|
||||
|
||||
genes = bird.genes;
|
||||
birthTime = uint256(bird.birthTime);
|
||||
mumId = uint256(bird.mumId);
|
||||
dadId = uint256(bird.dadId);
|
||||
generation = uint256(bird.generation);
|
||||
}
|
||||
|
||||
function getAllBirdsOfOwner(address owner) external view returns(uint256[] memory) {
|
||||
uint256[] memory allBirdsOfOwner = new uint[](ownsNumberOfTokens[owner]);
|
||||
uint256 j = 0;
|
||||
for (uint256 i = 0; i < birdies.length; i++) {
|
||||
if (birdOwner[i] == owner) {
|
||||
allBirdsOfOwner[j] = i;
|
||||
j = SafeMath.add(j, 1);
|
||||
}
|
||||
}
|
||||
return allBirdsOfOwner;
|
||||
}
|
||||
|
||||
function balanceOf(address owner) external view returns (uint256 balance) {
|
||||
return ownsNumberOfTokens[owner];
|
||||
}
|
||||
|
||||
function totalSupply() external view returns (uint256 total) {
|
||||
return birdies.length;
|
||||
}
|
||||
|
||||
function name() external view returns (string memory tokenName){
|
||||
return _name;
|
||||
}
|
||||
|
||||
function symbol() external view returns (string memory tokenSymbol){
|
||||
return _symbol;
|
||||
}
|
||||
|
||||
function ownerOf(uint256 tokenId) external view returns (address owner) {
|
||||
require(tokenId < birdies.length, "Token ID doesn't exist.");
|
||||
return birdOwner[tokenId];
|
||||
}
|
||||
|
||||
function transfer(address to, uint256 tokenId) external {
|
||||
require(to != address(0), "Use the burn function to burn tokens!");
|
||||
require(to != address(this), "Wrong address, try again!");
|
||||
require(birdOwner[tokenId] == msg.sender);
|
||||
_transfer(msg.sender, to, tokenId);
|
||||
}
|
||||
|
||||
function _transfer(address _from, address _to, uint256 _tokenId) internal {
|
||||
require(_to != address(this));
|
||||
ownsNumberOfTokens[_to] = SafeMath.add(ownsNumberOfTokens[_to], 1);
|
||||
birdOwner[_tokenId] = _to;
|
||||
|
||||
if (_from != address(0)) {
|
||||
ownsNumberOfTokens[_from] = SafeMath.sub(ownsNumberOfTokens[_from], 1);
|
||||
delete approvalOneBird[_tokenId];//when owner changes, approval must be removed.
|
||||
}
|
||||
|
||||
emit Transfer(_from, _to, _tokenId);
|
||||
}
|
||||
|
||||
function approve(address _approved, uint256 _tokenId) external {
|
||||
require(birdOwner[_tokenId] == msg.sender || _operatorApprovals[birdOwner[_tokenId]][msg.sender] == true,
|
||||
"You are not authorized to access this function.");
|
||||
approvalOneBird[_tokenId] = _approved;
|
||||
emit Approval(msg.sender, _approved, _tokenId);
|
||||
}
|
||||
|
||||
function setApprovalForAll(address _operator, bool _approved) external {
|
||||
require(_operator != msg.sender);
|
||||
_operatorApprovals[msg.sender][_operator] = _approved;
|
||||
emit ApprovalForAll(msg.sender, _operator, _approved);
|
||||
}
|
||||
|
||||
function getApproved(uint256 _tokenId) external view returns (address) {
|
||||
require(_tokenId < birdies.length, "Token doesn't exist");
|
||||
return approvalOneBird[_tokenId];
|
||||
}
|
||||
|
||||
function isApprovedForAll(address _owner, address _operator) external view returns (bool) {
|
||||
return _operatorApprovals[_owner][_operator];
|
||||
}
|
||||
|
||||
function _safeTransfer(address _from, address _to, uint256 _tokenId, bytes memory _data) internal {
|
||||
require(_checkERC721Support(_from, _to, _tokenId, _data));
|
||||
_transfer(_from, _to, _tokenId);
|
||||
}
|
||||
|
||||
function _checkERC721Support(address _from, address _to, uint256 _tokenId, bytes memory _data)
|
||||
internal returns(bool) {
|
||||
if(!_isContract(_to)) {
|
||||
return true;
|
||||
}
|
||||
bytes4 returnData = IERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data);
|
||||
//Call onERC721Received in the _to contract
|
||||
return returnData == _ERC721Checksum;
|
||||
//Check return value
|
||||
}
|
||||
|
||||
function _isContract(address _to) internal view returns (bool) {
|
||||
uint32 size;
|
||||
assembly{
|
||||
size := extcodesize(_to)
|
||||
}
|
||||
return size > 0;
|
||||
//check if code size > 0; wallets have 0 size.
|
||||
}
|
||||
|
||||
function _isOwnerOrApproved(address _from, address _to, uint256 _tokenId) internal view returns (bool) {
|
||||
require(_from == msg.sender ||
|
||||
approvalOneBird[_tokenId] == msg.sender ||
|
||||
_operatorApprovals[_from][msg.sender],
|
||||
"You are not authorized to use this function");
|
||||
require(birdOwner[_tokenId] == _from, "Owner incorrect");
|
||||
require(_to != address(0), "Error: Operation would delete this token permanently");
|
||||
require(_tokenId < birdies.length, "Token doesn't exist");
|
||||
return true;
|
||||
}
|
||||
|
||||
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external {
|
||||
_isOwnerOrApproved(_from, _to, _tokenId);
|
||||
_safeTransfer(_from, _to, _tokenId, data);
|
||||
}
|
||||
|
||||
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external {
|
||||
_isOwnerOrApproved(_from, _to, _tokenId);
|
||||
_safeTransfer(_from, _to, _tokenId, "");
|
||||
}
|
||||
|
||||
function transferFrom(address _from, address _to, uint256 _tokenId) external {
|
||||
_isOwnerOrApproved(_from, _to, _tokenId);
|
||||
_transfer(_from, _to, _tokenId);
|
||||
}
|
||||
|
||||
function _mixDna(
|
||||
uint256 _dadDna,
|
||||
uint256 _mumDna,
|
||||
uint8 random,
|
||||
uint8 randomSeventeenthDigit,
|
||||
uint8 randomPair,
|
||||
uint8 randomNumberForRandomPair
|
||||
) internal pure returns (uint256){
|
||||
|
||||
uint256[9] memory geneArray;
|
||||
uint256 i;
|
||||
uint256 counter = 7; // start on the right end
|
||||
|
||||
//DNA example: 11 22 33 44 55 66 77 88 9
|
||||
|
||||
if(randomSeventeenthDigit == 0){
|
||||
geneArray[8] = uint8(_mumDna % 10); //this takes the 17th gene from mum.
|
||||
} else {
|
||||
geneArray[8] = uint8(_dadDna % 10); //this takes the 17th gene from dad.
|
||||
}
|
||||
|
||||
_mumDna = SafeMath.div(_mumDna, 10); // division by 10 removes the last digit
|
||||
_dadDna = SafeMath.div(_dadDna, 10); // division by 10 removes the last digit
|
||||
|
||||
for (i = 1; i <= 128; i=i*2) { //1, 2 , 4, 8, 16, 32, 64 ,128
|
||||
if(random & i == 0){ //00000001
|
||||
geneArray[counter] = uint8(_mumDna % 100); //00000010 etc.
|
||||
} else { //11001011 &
|
||||
geneArray[counter] = uint8(_dadDna % 100); //00000001 will go through random number bitwise
|
||||
} //if(1) - dad gene
|
||||
_mumDna = SafeMath.div(_mumDna, 100); //if(0) - mum gene
|
||||
_dadDna = SafeMath.div(_dadDna, 100); //division by 100 removes last two digits from genes
|
||||
if(counter > 0) {
|
||||
counter = SafeMath.sub(counter, 1);
|
||||
}
|
||||
}
|
||||
|
||||
geneArray[randomPair] = randomNumberForRandomPair; //extra randomness for random pair.
|
||||
|
||||
uint256 newGene = 0;
|
||||
|
||||
//geneArray example: [11, 22, 33, 44, 55, 66, 77, 88, 9]
|
||||
|
||||
for (i = 0; i < 8; i++) { //8 is number of pairs in array
|
||||
newGene = SafeMath.mul(newGene, 100); //adds two digits to newGene; no digits the first time
|
||||
newGene = SafeMath.add(newGene, geneArray[i]); //adds a pair of genes
|
||||
}
|
||||
newGene = SafeMath.mul(newGene, 10); //add seventeenth digit
|
||||
newGene = SafeMath.add(newGene, geneArray[8]);
|
||||
return newGene;
|
||||
}
|
||||
}
|
10
contracts/Destroyable.sol
Normal file
@ -0,0 +1,10 @@
|
||||
pragma solidity ^0.5.12;
|
||||
|
||||
import "./Ownable.sol";
|
||||
|
||||
contract Destroyable is Ownable{
|
||||
|
||||
function close() public onlyOwner {
|
||||
selfdestruct(_owner);
|
||||
}
|
||||
}
|
24
contracts/IERC165.sol
Normal file
@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.5.12;
|
||||
|
||||
/**
|
||||
* @dev Interface of the ERC165 standard, as defined in the
|
||||
* https://eips.ethereum.org/EIPS/eip-165[EIP].
|
||||
*
|
||||
* Implementers can declare support of contract interfaces, which can then be
|
||||
* queried by others ({ERC165Checker}).
|
||||
*
|
||||
* For an implementation, see {ERC165}.
|
||||
*/
|
||||
interface IERC165 {
|
||||
/**
|
||||
* @dev Returns true if this contract implements the interface defined by
|
||||
* `interfaceId`. See the corresponding
|
||||
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
|
||||
* to learn more about how these ids are created.
|
||||
*
|
||||
* This function call must use less than 30 000 gas.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) external view returns (bool);
|
||||
}
|
125
contracts/IERC721.sol
Normal file
@ -0,0 +1,125 @@
|
||||
pragma solidity ^0.5.0;
|
||||
/**
|
||||
* @dev Required interface of an ERC721 compliant contract.
|
||||
*/
|
||||
interface IERC721 {
|
||||
/**
|
||||
* @dev Emitted when `tokenId` token is transfered from `from` to `to`.
|
||||
*/
|
||||
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
|
||||
|
||||
/**
|
||||
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
|
||||
*/
|
||||
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
|
||||
|
||||
/**
|
||||
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
|
||||
*/
|
||||
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
|
||||
|
||||
/**
|
||||
* @dev Returns the number of tokens in ``owner``'s account.
|
||||
*/
|
||||
function balanceOf(address owner) external view returns (uint256 balance);
|
||||
|
||||
/*
|
||||
* @dev Returns the total number of tokens in circulation.
|
||||
*/
|
||||
function totalSupply() external view returns (uint256 total);
|
||||
|
||||
/*
|
||||
* @dev Returns the name of the token.
|
||||
*/
|
||||
function name() external view returns (string memory tokenName);
|
||||
|
||||
/*
|
||||
* @dev Returns the symbol of the token.
|
||||
*/
|
||||
function symbol() external view returns (string memory tokenSymbol);
|
||||
|
||||
/**
|
||||
* @dev Returns the owner of the `tokenId` token.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - `tokenId` must exist.
|
||||
*/
|
||||
function ownerOf(uint256 tokenId) external view returns (address owner);
|
||||
|
||||
|
||||
/* @dev Transfers `tokenId` token from `msg.sender` to `to`.
|
||||
*
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - `to` cannot be the zero address.
|
||||
* - `to` can not be the contract address.
|
||||
* - `tokenId` token must be owned by `msg.sender`.
|
||||
*
|
||||
* Emits a {Transfer} event.
|
||||
*/
|
||||
function transfer(address to, uint256 tokenId) external;
|
||||
|
||||
/// @notice Change or reaffirm the approved address for an NFT
|
||||
/// @dev The zero address indicates there is no approved address.
|
||||
/// Throws unless `msg.sender` is the current NFT owner, or an authorized
|
||||
/// operator of the current owner.
|
||||
/// @param _approved The new approved NFT controller
|
||||
/// @param _tokenId The NFT to approve
|
||||
function approve(address _approved, uint256 _tokenId) external;
|
||||
|
||||
/// @notice Enable or disable approval for a third party ("operator") to manage
|
||||
/// all of `msg.sender`'s assets
|
||||
/// @dev Emits the ApprovalForAll event. The contract MUST allow
|
||||
/// multiple operators per owner.
|
||||
/// @param _operator Address to add to the set of authorized operators
|
||||
/// @param _approved True if the operator is approved, false to revoke approval
|
||||
function setApprovalForAll(address _operator, bool _approved) external;
|
||||
|
||||
/// @notice Get the approved address for a single NFT
|
||||
/// @dev Throws if `_tokenId` is not a valid NFT.
|
||||
/// @param _tokenId The NFT to find the approved address for
|
||||
/// @return The approved address for this NFT, or the zero address if there is none
|
||||
function getApproved(uint256 _tokenId) external view returns (address);
|
||||
|
||||
/// @notice Query if an address is an authorized operator for another address
|
||||
/// @param _owner The address that owns the NFTs
|
||||
/// @param _operator The address that acts on behalf of the owner
|
||||
/// @return True if `_operator` is an approved operator for `_owner`, false otherwise
|
||||
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
|
||||
|
||||
/// @notice Transfers the ownership of an NFT from one address to another address
|
||||
/// @dev Throws unless `msg.sender` is the current owner, an authorized
|
||||
/// operator, or the approved address for this NFT. Throws if `_from` is
|
||||
/// not the current owner. Throws if `_to` is the zero address. Throws if
|
||||
/// `_tokenId` is not a valid NFT. When transfer is complete, this function
|
||||
/// checks if `_to` is a smart contract (code size > 0). If so, it calls
|
||||
/// `onERC721Received` on `_to` and throws if the return value is not
|
||||
/// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
|
||||
/// @param _from The current owner of the NFT
|
||||
/// @param _to The new owner
|
||||
/// @param _tokenId The NFT to transfer
|
||||
/// @param data Additional data with no specified format, sent in call to `_to`
|
||||
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external;
|
||||
|
||||
/// @notice Transfers the ownership of an NFT from one address to another address
|
||||
/// @dev This works identically to the other function with an extra data parameter,
|
||||
/// except this function just sets data to "".
|
||||
/// @param _from The current owner of the NFT
|
||||
/// @param _to The new owner
|
||||
/// @param _tokenId The NFT to transfer
|
||||
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external;
|
||||
|
||||
/// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
|
||||
/// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
|
||||
/// THEY MAY BE PERMANENTLY LOST
|
||||
/// @dev Throws unless `msg.sender` is the current owner, an authorized
|
||||
/// operator, or the approved address for this NFT. Throws if `_from` is
|
||||
/// not the current owner. Throws if `_to` is the zero address. Throws if
|
||||
/// `_tokenId` is not a valid NFT.
|
||||
/// @param _from The current owner of the NFT
|
||||
/// @param _to The new owner
|
||||
/// @param _tokenId The NFT to transfer
|
||||
function transferFrom(address _from, address _to, uint256 _tokenId) external;
|
||||
}
|
5
contracts/IERC721Receiver.sol
Normal file
@ -0,0 +1,5 @@
|
||||
pragma solidity ^0.5.12;
|
||||
|
||||
interface IERC721Receiver {
|
||||
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
|
||||
}
|
82
contracts/IMarketplace.sol
Normal file
@ -0,0 +1,82 @@
|
||||
pragma solidity ^0.5.12;
|
||||
|
||||
import "./CryptoBirdies.sol";
|
||||
import "./Ownable.sol";
|
||||
|
||||
/*
|
||||
* Market place to trade birds (should **in theory** be used for any ERC721 token)
|
||||
* It needs an existing bird contract to interact with
|
||||
* Note: it does not inherit from the contract
|
||||
* Note: It takes ownership of the bird for the duration that is is on the marketplace.
|
||||
*/
|
||||
interface IMarketPlace {
|
||||
|
||||
event MarketTransaction(string TxType, address owner, uint256 tokenId);
|
||||
event MonetaryTransaction(string message, address recipient, uint256 amount);
|
||||
|
||||
/**
|
||||
* Set the current contract address and initialize the instance of the contract.
|
||||
* Requirement: Only the contract owner can call.
|
||||
*/
|
||||
function setContract(address _contractAddress) external;
|
||||
|
||||
/**
|
||||
* Sets status of _paused to true which affects all functions that have whenNotPaused modifiers.
|
||||
*/
|
||||
function pause() external;
|
||||
|
||||
/**
|
||||
* Sets status of _paused to false which affects all functions that have whenNotPaused modifiers.
|
||||
*/
|
||||
function resume() external;
|
||||
|
||||
/**
|
||||
* Get the details about a offer for _tokenId. Throws an error if there is no active offer for _tokenId.
|
||||
*/
|
||||
function getOffer(uint256 _tokenId) external view returns (address seller, uint256 price, uint256 index, uint256 tokenId, bool active);
|
||||
|
||||
/**
|
||||
* Get all tokenId's that are currently for sale. Returns an empty array if no offer exists.
|
||||
*/
|
||||
function getAllTokensOnSale() external view returns (uint256[] memory listOfOffers);
|
||||
|
||||
/**
|
||||
* Creates a new offer for _tokenId for the price _price.
|
||||
* Emits the MarketTransaction event with txType "Create offer"
|
||||
* Requirement: Only the owner of _tokenId can create an offer.
|
||||
* Requirement: There can only be one active offer for a token at a time.
|
||||
* Requirement: Marketplace contract (this) needs to be an approved operator when the offer is created.
|
||||
*/
|
||||
function setOffer(uint256 _price, uint256 _tokenId) external;
|
||||
|
||||
/**
|
||||
* Removes an existing offer.
|
||||
* Emits the MarketTransaction event with txType "Remove offer"
|
||||
* Requirement: Only the seller of _tokenId can remove an offer.
|
||||
*/
|
||||
function removeOffer(uint256 _tokenId) external;
|
||||
|
||||
/**
|
||||
* Executes the purchase of _tokenId.
|
||||
* Transfers the token using transferFrom in CryptoBirdies.
|
||||
* Transfers funds to the _fundsToBeCollected mapping.
|
||||
* Removes the offer from the mapping.
|
||||
* Sets the offer in the array to inactive.
|
||||
* Emits the MarketTransaction event with txType "Buy".
|
||||
* Requirement: The msg.value needs to equal the price of _tokenId
|
||||
* Requirement: There must be an active offer for _tokenId
|
||||
*/
|
||||
function buyBird(uint256 _tokenId) external payable;
|
||||
|
||||
/**
|
||||
* Returns current balance of msg.sender
|
||||
*/
|
||||
function getBalance() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* Send funds to msg.sender.
|
||||
* Emits a MonetaryTransaction event "Successful Transfer".
|
||||
* Requirement: msg.sender must have funds in the mapping.
|
||||
*/
|
||||
function withdrawFunds() external payable;
|
||||
}
|
193
contracts/Marketplace.sol
Normal file
@ -0,0 +1,193 @@
|
||||
pragma solidity ^0.5.12;
|
||||
|
||||
import "./CryptoBirdies.sol";
|
||||
import "./Ownable.sol";
|
||||
import "./IMarketplace.sol";
|
||||
import "./SafeMath.sol";
|
||||
|
||||
/*
|
||||
* Market place to trade birds (should **in theory** be used for any ERC721 token)
|
||||
* It needs an existing bird contract to interact with
|
||||
* Note: it does not inherit from the contract
|
||||
* Note: It takes ownership of the bird for the duration that is is on the marketplace.
|
||||
*/
|
||||
|
||||
contract MarketPlace is Ownable, IMarketPlace {
|
||||
CryptoBirdies private _cryptoBirdies;
|
||||
|
||||
using SafeMath for uint256;
|
||||
|
||||
struct Offer {
|
||||
address payable seller;
|
||||
uint256 price;
|
||||
uint256 index;
|
||||
uint256 tokenId;
|
||||
bool active;
|
||||
}
|
||||
|
||||
bool internal _paused;
|
||||
|
||||
Offer[] offers;
|
||||
|
||||
mapping(uint256 => Offer) tokenIdToOffer;
|
||||
mapping(address => uint256) internal _fundsToBeCollected;
|
||||
|
||||
//Contract has one event that is already declared in the interface.
|
||||
|
||||
//Contract can be paused by owner to ensure bugs can be fixed after deployment
|
||||
modifier whenNotPaused() {
|
||||
require(!_paused);
|
||||
_;
|
||||
}
|
||||
|
||||
modifier whenPaused() {
|
||||
require(_paused);
|
||||
_;
|
||||
}
|
||||
|
||||
function setContract(address _contractAddress) onlyOwner public {
|
||||
_cryptoBirdies = CryptoBirdies(_contractAddress);
|
||||
}
|
||||
|
||||
constructor(address _contractAddress) public {
|
||||
setContract(_contractAddress);
|
||||
_paused = false;
|
||||
}
|
||||
|
||||
function pause() public onlyOwner whenNotPaused {
|
||||
_paused = true;
|
||||
}
|
||||
|
||||
function resume() public onlyOwner whenPaused {
|
||||
_paused = false;
|
||||
}
|
||||
|
||||
function isPaused() public view returns (bool) {
|
||||
return _paused;
|
||||
}
|
||||
|
||||
function getOffer(uint256 _tokenId) public view returns (
|
||||
address seller,
|
||||
uint256 price,
|
||||
uint256 index,
|
||||
uint256 tokenId,
|
||||
bool active) {
|
||||
|
||||
require(tokenIdToOffer[_tokenId].active == true, "No active offer at this time");
|
||||
|
||||
return (tokenIdToOffer[_tokenId].seller,
|
||||
tokenIdToOffer[_tokenId].price,
|
||||
tokenIdToOffer[_tokenId].index,
|
||||
tokenIdToOffer[_tokenId].tokenId,
|
||||
tokenIdToOffer[_tokenId].active);
|
||||
}
|
||||
|
||||
function getAllTokensOnSale() public view returns (uint256[] memory listOfOffers) {
|
||||
uint256 resultId = 0;//index for all birds with active offer status (true)
|
||||
|
||||
for (uint256 index = 0; index < offers.length; index++) {
|
||||
if (offers[index].active == true) {
|
||||
resultId = SafeMath.add(resultId, 1);//determine length of array to return
|
||||
}
|
||||
}
|
||||
|
||||
if (offers.length == 0) {
|
||||
return new uint256[](0);//returns empty array
|
||||
} else {
|
||||
uint256[] memory allTokensOnSale = new uint256[](resultId);
|
||||
//initialize new array with correct length
|
||||
resultId = 0;//reset index of new array
|
||||
for (uint256 index = 0; index < offers.length; index++) {//iterate through entire offers array
|
||||
if (offers[index].active == true) {
|
||||
allTokensOnSale[resultId] = offers[index].tokenId;
|
||||
resultId = SafeMath.add(resultId, 1);
|
||||
}
|
||||
}
|
||||
return allTokensOnSale;
|
||||
}
|
||||
}
|
||||
|
||||
function _ownsBird(address _address, uint256 _tokenId) internal view returns (bool) {
|
||||
return (_cryptoBirdies.ownerOf(_tokenId) == _address);
|
||||
}
|
||||
|
||||
function setOffer(uint256 _price, uint256 _tokenId) public {
|
||||
require(_ownsBird(msg.sender, _tokenId),
|
||||
"Only the owner of the bird can initialize an offer");
|
||||
require(tokenIdToOffer[_tokenId].active == false,
|
||||
"You already created an offer for this bird. Please remove it first before creating a new one.");
|
||||
require(_cryptoBirdies.isApprovedForAll(msg.sender, address(this)),
|
||||
"MarketPlace contract must first be an approved operator for your birds");
|
||||
|
||||
Offer memory _currentOffer = Offer({//set offer
|
||||
seller: msg.sender,
|
||||
price: _price,
|
||||
index: offers.length,
|
||||
tokenId: _tokenId,
|
||||
active: true
|
||||
});
|
||||
|
||||
tokenIdToOffer[_tokenId] = _currentOffer;//update mapping
|
||||
offers.push(_currentOffer);//update array
|
||||
|
||||
emit MarketTransaction("Offer created", msg.sender, _tokenId);
|
||||
}
|
||||
|
||||
function removeOffer(uint256 _tokenId) public {
|
||||
require(tokenIdToOffer[_tokenId].seller == msg.sender,
|
||||
"Only the owner of the bird can withdraw the offer.");
|
||||
|
||||
offers[tokenIdToOffer[_tokenId].index].active = false;
|
||||
//don't iterate through array, simply set active to false.
|
||||
delete tokenIdToOffer[_tokenId];//delete entry in mapping
|
||||
|
||||
emit MarketTransaction("Offer removed", msg.sender, _tokenId);
|
||||
}
|
||||
|
||||
function buyBird(uint256 _tokenId) public payable whenNotPaused{
|
||||
Offer memory _currentOffer = tokenIdToOffer[_tokenId];
|
||||
|
||||
//checks
|
||||
require(_currentOffer.active, "There is no active offer for this bird");
|
||||
require(msg.value == _currentOffer.price, "The amount offered is not equal to the requested amount");
|
||||
|
||||
//effects
|
||||
delete tokenIdToOffer[_tokenId];//delete entry in mapping
|
||||
offers[_currentOffer.index].active = false;//don't iterate through array, but simply set active to false.
|
||||
|
||||
//interactions
|
||||
if (_currentOffer.price > 0) {
|
||||
_fundsToBeCollected[_currentOffer.seller] =
|
||||
SafeMath.add(_fundsToBeCollected[_currentOffer.seller], _currentOffer.price);
|
||||
//instead of sending money to seller it is deposited in a mapping waiting for seller to pull.
|
||||
}
|
||||
|
||||
_cryptoBirdies.transferFrom(_currentOffer.seller, msg.sender, _tokenId);//ERC721 ownership transferred
|
||||
|
||||
emit MarketTransaction("Bird successfully purchased", msg.sender, _tokenId);
|
||||
}
|
||||
|
||||
function getBalance() public view returns (uint256) {
|
||||
return _fundsToBeCollected[msg.sender];
|
||||
}
|
||||
|
||||
function withdrawFunds() public payable whenNotPaused{
|
||||
|
||||
//check
|
||||
require(_fundsToBeCollected[msg.sender] > 0, "No funds available at this time");
|
||||
|
||||
uint256 toWithdraw = _fundsToBeCollected[msg.sender];
|
||||
|
||||
//effect
|
||||
_fundsToBeCollected[msg.sender] = 0;
|
||||
|
||||
//interaction
|
||||
msg.sender.transfer(toWithdraw);
|
||||
|
||||
//making sure transfer executed correctly
|
||||
assert(_fundsToBeCollected[msg.sender] == 0);
|
||||
|
||||
//emit event
|
||||
emit MonetaryTransaction("Funds successfully received", msg.sender, toWithdraw);
|
||||
}
|
||||
}
|
19
contracts/Migrations.sol
Normal file
@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.4.22 <0.8.0;
|
||||
|
||||
contract Migrations {
|
||||
address public _owner = msg.sender;
|
||||
uint public _last_completed_migration;
|
||||
|
||||
modifier restricted() {
|
||||
require(
|
||||
msg.sender == _owner,
|
||||
"This function is restricted to the contract's owner"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
function setCompleted(uint _completed) public restricted {
|
||||
_last_completed_migration = _completed;
|
||||
}
|
||||
}
|
16
contracts/Ownable.sol
Normal file
@ -0,0 +1,16 @@
|
||||
pragma solidity ^0.5.12;
|
||||
|
||||
contract Ownable{
|
||||
|
||||
address payable internal _owner;
|
||||
|
||||
modifier onlyOwner(){
|
||||
require(msg.sender == _owner,
|
||||
"You need to be owner of the contract in order to access this functionality!");
|
||||
_;
|
||||
}
|
||||
|
||||
constructor() public{
|
||||
_owner = msg.sender;
|
||||
}
|
||||
}
|
159
contracts/Safemath.sol
Normal file
@ -0,0 +1,159 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.5.12;
|
||||
|
||||
/**
|
||||
* @dev Wrappers over Solidity's arithmetic operations with added overflow
|
||||
* checks.
|
||||
*
|
||||
* Arithmetic operations in Solidity wrap on overflow. This can easily result
|
||||
* in bugs, because programmers usually assume that an overflow raises an
|
||||
* error, which is the standard behavior in high level programming languages.
|
||||
* `SafeMath` restores this intuition by reverting the transaction when an
|
||||
* operation overflows.
|
||||
*
|
||||
* Using this library instead of the unchecked operations eliminates an entire
|
||||
* class of bugs, so it's recommended to use it always.
|
||||
*/
|
||||
library SafeMath {
|
||||
/**
|
||||
* @dev Returns the addition of two unsigned integers, reverting on
|
||||
* overflow.
|
||||
*
|
||||
* Counterpart to Solidity's `+` operator.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - Addition cannot overflow.
|
||||
*/
|
||||
function add(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
uint256 c = a + b;
|
||||
require(c >= a, "SafeMath: addition overflow");
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the subtraction of two unsigned integers, reverting on
|
||||
* overflow (when the result is negative).
|
||||
*
|
||||
* Counterpart to Solidity's `-` operator.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - Subtraction cannot overflow.
|
||||
*/
|
||||
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
return sub(a, b, "SafeMath: subtraction overflow");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
|
||||
* overflow (when the result is negative).
|
||||
*
|
||||
* Counterpart to Solidity's `-` operator.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - Subtraction cannot overflow.
|
||||
*/
|
||||
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
|
||||
require(b <= a, errorMessage);
|
||||
uint256 c = a - b;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the multiplication of two unsigned integers, reverting on
|
||||
* overflow.
|
||||
*
|
||||
* Counterpart to Solidity's `*` operator.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - Multiplication cannot overflow.
|
||||
*/
|
||||
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
|
||||
// benefit is lost if 'b' is also tested.
|
||||
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint256 c = a * b;
|
||||
require(c / a == b, "SafeMath: multiplication overflow");
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the integer division of two unsigned integers. Reverts on
|
||||
* division by zero. The result is rounded towards zero.
|
||||
*
|
||||
* Counterpart to Solidity's `/` operator. Note: this function uses a
|
||||
* `revert` opcode (which leaves remaining gas untouched) while Solidity
|
||||
* uses an invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function div(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
return div(a, b, "SafeMath: division by zero");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
|
||||
* division by zero. The result is rounded towards zero.
|
||||
*
|
||||
* Counterpart to Solidity's `/` operator. Note: this function uses a
|
||||
* `revert` opcode (which leaves remaining gas untouched) while Solidity
|
||||
* uses an invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
|
||||
require(b > 0, errorMessage);
|
||||
uint256 c = a / b;
|
||||
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
|
||||
* Reverts when dividing by zero.
|
||||
*
|
||||
* Counterpart to Solidity's `%` operator. This function uses a `revert`
|
||||
* opcode (which leaves remaining gas untouched) while Solidity uses an
|
||||
* invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
return mod(a, b, "SafeMath: modulo by zero");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
|
||||
* Reverts with custom message when dividing by zero.
|
||||
*
|
||||
* Counterpart to Solidity's `%` operator. This function uses a `revert`
|
||||
* opcode (which leaves remaining gas untouched) while Solidity uses an
|
||||
* invalid opcode to revert (consuming all remaining gas).
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - The divisor cannot be zero.
|
||||
*/
|
||||
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
|
||||
require(b != 0, errorMessage);
|
||||
return a % b;
|
||||
}
|
||||
}
|
37
contracts/TestBirdies.sol
Normal file
@ -0,0 +1,37 @@
|
||||
pragma solidity ^0.5.12;
|
||||
|
||||
import "./CryptoBirdies.sol";
|
||||
|
||||
contract TestBirdies is CryptoBirdies {
|
||||
|
||||
constructor(string memory name, string memory symbol) CryptoBirdies(name, symbol) public{}
|
||||
|
||||
function testCreateBird(uint256 genes, address owner) public returns (uint256) {
|
||||
return _createBird(0, 0, 0, genes, owner);
|
||||
}
|
||||
|
||||
function testCreateGenXBird(uint256 generation, uint256 genes, address owner) public returns (uint256) {
|
||||
return _createBird(0, 0, generation, genes, owner);
|
||||
}
|
||||
|
||||
function testMixDna(
|
||||
uint256 _dadDna,
|
||||
uint256 _mumDna,
|
||||
uint8 random,
|
||||
uint8 randomSeventeenthDigit,
|
||||
uint8 randomPair,
|
||||
uint8 randomNumberForRandomPair
|
||||
) public pure returns (uint256){
|
||||
return _mixDna(
|
||||
_dadDna,
|
||||
_mumDna,
|
||||
random,
|
||||
randomSeventeenthDigit,
|
||||
randomPair,
|
||||
randomNumberForRandomPair);
|
||||
}
|
||||
|
||||
function testSetGenCounter(uint256 value) public returns (uint256){
|
||||
return gen0Counter = value;
|
||||
}
|
||||
}
|
14
contracts/TestErc.sol
Normal file
@ -0,0 +1,14 @@
|
||||
pragma solidity ^0.5.12;
|
||||
|
||||
import "./IERC721Receiver.sol";
|
||||
|
||||
contract TestErc is IERC721Receiver {
|
||||
|
||||
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4) {
|
||||
operator;//mention parameters only to suppress warnings in truffle
|
||||
from;
|
||||
tokenId;
|
||||
data;
|
||||
return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
|
||||
}
|
||||
}
|
48
contracts/TestMarket.sol
Normal file
@ -0,0 +1,48 @@
|
||||
pragma solidity ^0.5.12;
|
||||
|
||||
import "./Marketplace.sol";
|
||||
|
||||
contract TestMarket is MarketPlace {
|
||||
|
||||
constructor(address _contractAddress) MarketPlace(_contractAddress) public{}
|
||||
|
||||
function getOfferFromMapping(uint256 id) public view returns(
|
||||
address seller,
|
||||
uint256 price,
|
||||
uint256 index,
|
||||
uint256 tokenId,
|
||||
bool active) {
|
||||
|
||||
return (tokenIdToOffer[id].seller,
|
||||
tokenIdToOffer[id].price,
|
||||
tokenIdToOffer[id].index,
|
||||
tokenIdToOffer[id].tokenId,
|
||||
tokenIdToOffer[id].active);
|
||||
}
|
||||
|
||||
function getOfferFromArray(uint256 id) public view returns(
|
||||
address seller,
|
||||
uint256 price,
|
||||
uint256 index,
|
||||
uint256 tokenId,
|
||||
bool active) {
|
||||
|
||||
return (offers[id].seller,
|
||||
offers[id].price,
|
||||
offers[id].index,
|
||||
offers[id].tokenId,
|
||||
offers[id].active);
|
||||
}
|
||||
|
||||
function getBalanceOfMapping(address caller) public view returns(uint256 amount) {
|
||||
return _fundsToBeCollected[caller];
|
||||
}
|
||||
|
||||
function testSetBalance(uint256 amount) public payable {
|
||||
_fundsToBeCollected[msg.sender] = amount;
|
||||
}
|
||||
|
||||
function testSetPause() public onlyOwner {
|
||||
_paused = true;
|
||||
}
|
||||
}
|
5
migrations/1_initial_migration.js
Normal file
@ -0,0 +1,5 @@
|
||||
const Migrations = artifacts.require("Migrations");
|
||||
|
||||
module.exports = function(deployer) {
|
||||
deployer.deploy(Migrations);
|
||||
};
|
9
migrations/2_CryptoBirdies_migration.js
Normal file
@ -0,0 +1,9 @@
|
||||
const ERC721 = artifacts.require("CryptoBirdies");
|
||||
|
||||
module.exports = async function(deployer) {
|
||||
await deployer.deploy(ERC721, "CryptoBird", "CBX");
|
||||
const instance = await ERC721.deployed();
|
||||
if(instance) {
|
||||
console.log("CryptoBirdies successfully deployed.")
|
||||
}
|
||||
}
|
10
migrations/3_MarketPlace_migration.js
Normal file
@ -0,0 +1,10 @@
|
||||
const CryptoBirdies = artifacts.require("CryptoBirdies");
|
||||
const MarketPlace = artifacts.require("MarketPlace");
|
||||
|
||||
module.exports = async function(deployer) {
|
||||
await deployer.deploy(MarketPlace, CryptoBirdies.address);
|
||||
const instance = await MarketPlace.deployed();
|
||||
if(instance) {
|
||||
console.log("MarketPlace successfully deployed.")
|
||||
}
|
||||
}
|
3825
package-lock.json
generated
Normal file
31
package.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "crypto_birdies",
|
||||
"version": "1.0.0",
|
||||
"description": "This is a clone of the famous Crypto Kitties.\r For an idea how the game works, see here: https://guide.cryptokitties.co/guide/",
|
||||
"main": "truffle-config.js",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/TobyKreiselmaier/Crypto-Birdies.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/TobyKreiselmaier/Crypto-Birdies/issues"
|
||||
},
|
||||
"homepage": "https://github.com/TobyKreiselmaier/Crypto-Birdies#readme",
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"truffle-assertions": "^0.9.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@truffle/hdwallet-provider": "^1.1.1",
|
||||
"bip39": "^3.0.2",
|
||||
"dotenv": "^8.2.0"
|
||||
}
|
||||
}
|