Slide 1

Slide 1 text

from Swift to Solidity fassko www.kristaps.me

Slide 2

Slide 2 text

about me geek iOS and ο£Ώ developer crypto πŸˆβ¬› at

Slide 3

Slide 3 text

Mr. Byte

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Solidity ECMAScript like syntax Static typing Multiple inheritance

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

– swift.org β€œSwift is designed to make writing and maintaining correct programs easier for the developer.”

Slide 11

Slide 11 text

Swift Safe Fast Expressive

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Deterministic adjective Believing that everything that happens must happen as it does and could not have happened any other way.

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

Multi-party agreement Agreement between πŸ‡ΊπŸ‡¦, πŸ‡·πŸ‡Ί and πŸ‡ΉπŸ‡· (supported by πŸ‡ΊπŸ‡³). πŸ‡·πŸ‡Ί will not target ports while shipments are in transit. πŸ‡ΊπŸ‡¦ vessels will guide cargo ships through waters that have been mined. πŸ‡ΉπŸ‡· - supported by the πŸ‡ΊπŸ‡³ - will inspect ships, to allay πŸ‡·πŸ‡Ί fears of weapons smuggling.

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

Logistics β€’ πŸ‡ΊπŸ‡¦ registers shipment β€’ The ship goes from πŸ‡ΊπŸ‡¦ to πŸ‡ΉπŸ‡· through mines β€’ πŸ‡ΉπŸ‡· checks ship if nothing is being smuggled β€’ The ship leaves πŸ‡ΉπŸ‡· β€’ Arrives in the destination country, πŸ‡ΊπŸ‡³ approves

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

Agreement address private ukraine; address private russia; address private turkey; address private un; bool private ukraineSigned; bool private russiaSigned; bool private turkeySigned; bool private unSigned; event SignedByUkraine(); event SignedByRussia(); event SignedByTurkey(); event SignedByUN(); event AgreementSigned(); Wallet addresses Signed status Sign event

Slide 20

Slide 20 text

Initial setup constructor(address _ukraine, address _russia, address _turkey, address _un) { ukraine = _ukraine; russia = _russia; turkey = _turkey; un = _un; }

Slide 21

Slide 21 text

Agreement function sign() external { console.log("Signer address", msg.sender); require(msg.sender == ukraine || msg.sender == russia || msg.sender == turkey || msg.sender == un, "Unknown signer"); if (msg.sender == ukraine) { ukraineSigned = true; emit SignedByUkraine(); } if (msg.sender == russia) { russiaSigned = true; emit SignedByRussia(); } if (msg.sender == turkey) { turkeySigned = true; emit SignedByTurkey(); } if (msg.sender == un) { unSigned = true; emit SignedByUN(); } if (ukraineSigned && russiaSigned && turkeySigned && unSigned) { emit AgreementSigned(); } } Emit event Check wallet address Agreement signed

Slide 22

Slide 22 text

Agreement struct ContentView: View { @StateObject var appData = AppData() private var agreementSigned: Bool { appData.ukraineSigned && appData.russiaSigned && appData.turkeySigned && appData.unSigned } var body: some View { NavigationStack { VStack(spacing: 30) { Spacer() CountryButtonView(country: .ukraine) { appData.ukraineSigned = true }.disabled(appData.ukraineSigned) CountryButtonView(country: .russia) { appData.russiaSigned = true }.disabled(appData.russiaSigned) CountryButtonView(country: .turkey) { appData.turkeySigned = true }.disabled(appData.turkeySigned) CountryButtonView(country: .un) { appData.unSigned = true }.disabled(appData.unSigned) Spacer() NavigationLink { ShipmentView() } label: { Text("Next") .font(.title2) } .disabled(!agreementSigned) } } .environmentObject(appData) } }

Slide 23

Slide 23 text

πŸ‡ΊπŸ‡¦ signed CountryButtonView(country: .ukraine) { appData.ukraineSigned = true } .disabled(appData.ukraineSigned)

Slide 24

Slide 24 text

Agreement signed @StateObject var appData = AppData() private var agreementSigned: Bool { appData.ukraineSigned && appData.russiaSigned && appData.turkeySigned && appData.unSigned } NavigationLink { ShipmentView() } label: { Text("Next") .font(.title2) } .disabled(!agreementSigned)

Slide 25

Slide 25 text

AppData class AppData: ObservableObject { @Published var ukraineSigned: Bool = false @Published var russiaSigned: Bool = false @Published var turkeySigned: Bool = false @Published var unSigned: Bool = false

Slide 26

Slide 26 text

Modi fi er modifier agreementSigned() { require(ukraineSigned, "Ukraine not signed"); require(russiaSigned, "Russia not signed"); require(turkeySigned, "Turkey not signed"); require(unSigned, "United Nations not signed"); _; }

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

ShipmentStatus enum ShipmentStatus { InUkraine, // Registered in Ukraine LeftUkraine, // Navigating in Black Sea ArrivedInTurkey, // Arrived in Turkey LeftTurkey, // Left Turkey ArrivedInDestinationCountry // Arrived to the destination country } enum ShipmentStatus { case inUkraine // Registered in Ukraine case leftUkraine // Navigating in Black Sea case arrivedInTurkey // Arrived in Turkey case leftTurkey // Left Turkey case arrivedInDestinationCountry // Arrived to the destination country }

Slide 29

Slide 29 text

Shipment struct Shipment { string destination; ShipmentStatus status; } struct Shipment: Identifiable { var id: Int var destination: String var status: ShipmentStatus }

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

Create shipment - Solidity function createShipment(string memory _destination) external agreementSigned { require(msg.sender == ukraine, "Caller is not Ukraine"); currentShipmentId++; shipments[currentShipmentId] = Shipment(_destination, ShipmentStatus.InUkraine); console.log("Shipment created", currentShipmentId); emit ShipmentCreated(currentShipmentId); }

Slide 32

Slide 32 text

Create shipment - iOS struct AddShipmentView: View { @Environment(\.presentationMode) var presentationMode @EnvironmentObject var appData: AppData @State private var destination: String = "" var body: some View { NavigationStack { Form { Section { TextField("Destination", text: $destination) } Section { Button("Save", action: saveShipment) } } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("Cancel", action: closeModal) } } } } }

Slide 33

Slide 33 text

Create shipment - iOS func saveShipment() { let shipment = Shipment( id: Int(Date().timeIntervalSince1970), destination: destination, status: .inUkraine ) Task { @MainActor in appData.shipments.append(shipment) } closeModal() }

Slide 34

Slide 34 text

Left Ukraine - Solidity function leftUkraine(uint256 shipmentId) external agreementSigned { require(msg.sender == ukraine, "Caller is not Ukraine"); shipments[shipmentId].status = ShipmentStatus.LeftUkraine; console.log("Shipment left Ukraine", shipmentId); emit ShipmentLeftUkraine(shipmentId); }

Slide 35

Slide 35 text

Left Ukraine - iOS .sheet(item: $selectedShipment) { shipment in ChangeShipmentStatusView(shipment: shipment) .presentationDetents([.height(200)]) }

Slide 36

Slide 36 text

Left Ukraine - iOS struct ChangeShipmentStatusView: View { @EnvironmentObject var appData: AppData @Environment(\.presentationMode) var presentationMode @State private var showSelectCountryAlert = false var shipment: Shipment private var nextStatus: ShipmentStatus { switch shipment.status { case .inUkraine: return .leftUkraine case .leftUkraine: return .arrivedInTurkey case .arrivedInTurkey: return .leftTurkey case .leftTurkey: return .arrivedInDestinationCountry case .arrivedInDestinationCountry: return .arrivedInDestinationCountry } }

Slide 37

Slide 37 text

Left Ukraine - iOS var body: some View { NavigationStack { VStack { Button { changeStatusFor(to: nextStatus) } label: { Text(nextStatus.description) .font(.title3) .padding(10) } .buttonStyle(.borderedProminent) } } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("Cancel", action: closeModal) } } .alert(isPresented: $showSelectCountryAlert) { Alert( title: Text("Please select correct country"), message: Text("To continue please select correct country") ) } } }

Slide 38

Slide 38 text

Arrives in Turkey - Solidity function arrivesInTurkey(uint256 shipmentId) external agreementSigned { require(msg.sender == turkey, "Caller is not Turkey"); shipments[shipmentId].status = ShipmentStatus.ArrivedInTurkey; console.log("Shipment arrived in Turkey", shipmentId); emit ShipmentArrivedInTurkey(shipmentId); }

Slide 39

Slide 39 text

Arrives in Turkey - Swift func changeStatusFor(to status: ShipmentStatus) { var shipment = shipment switch status { case .inUkraine: return /// case .arrivedInTurkey: guard checkCountryIfSelectedIs(.turkey) else { showSelectCountryAlert = true return } shipment.status = .arrivedInTurkey

Slide 40

Slide 40 text

Arrives in Turkey - Swift .sheet(isPresented: $showCountrySwitch) { VStack { CountryButtonView(country: .ukraine, font: .body) { appData.activeCountry = .ukraine closeSheet() } CountryButtonView(country: .russia, font: .body) { appData.activeCountry = .russia closeSheet() } CountryButtonView(country: .turkey, font: .body) { appData.activeCountry = .turkey closeSheet() } CountryButtonView(country: .un, font: .body) { appData.activeCountry = .un closeSheet() } } .presentationDetents([.medium]) .padding(.vertical, 40) }

Slide 41

Slide 41 text

Arrives in Turkey - Swift case .arrivedInTurkey: guard checkCountryIfSelectedIs(.turkey) else { showSelectCountryAlert = true return } shipment.status = .arrivedInTurkey

Slide 42

Slide 42 text

Examined - Solidity function arrivesInTurkey(uint256 shipmentId) external agreementSigned { require(msg.sender == turkey, "Caller is not Turkey"); shipments[shipmentId].status = ShipmentStatus.ArrivedInTurkey; console.log("Shipment arrived in Turkey", shipmentId); emit ShipmentArrivedInTurkey(shipmentId); }

Slide 43

Slide 43 text

Examined - Swift case .leftTurkey: guard checkCountryIfSelectedIs(.turkey) else { showSelectCountryAlert = true return } shipment.status = .leftTurkey

Slide 44

Slide 44 text

Arrived in destination - Solidity function arrivedInDestination(uint256 shipmentId) external agreementSigned { require(msg.sender == un, "Caller is not United Nations"); shipments[shipmentId].status = ShipmentStatus.ArrivedInDestinationCountry; console.log("Shipment", shipmentId, "arrived in", shipments[shipmentId].destination); emit ShipmentArrivedInDestination(shipmentId, shipments[shipmentId].destination); }

Slide 45

Slide 45 text

Arrived in destination - Swift case .arrivedInDestinationCountry: guard checkCountryIfSelectedIs(.un) else { showSelectCountryAlert = true return } shipment.status = .arrivedInDestinationCountry

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

Similarities Statistically typed Data structures Inheritance - contract can extend from multiple contracts

Slide 49

Slide 49 text

Solidity Absence of null Primitive No Strings attached

Slide 50

Slide 50 text

Swift Modern Expressive Sugar

Slide 51

Slide 51 text

Blockchain β›“ Immutable Transparency Security

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

🀨 & πŸ€”

Slide 54

Slide 54 text

fassko www.kristaps.me

Slide 55

Slide 55 text

Materials Solidity app: github.com/fassko/grain-shipment-solidity Swift app: github.com/fassko/grain-shipments-ios